This is data.txt:
+----------------------------+---------+-------------------+
| Hostname | Plan | Server |
+----------------------------+---------+-------------------+
| hostname1 | B20C120 | R1SG7.myfqdn.com |
| another-host-name | B40G66 | R1DC8.myfqdn.com |
| the-other-hostname-is-here | B180G22 | R1SG8.myfqdn.com |
| last.mydomain.com | B400C88 | R1DG10.myfqdn.com |
+----------------------------+---------+-------------------+
This is my awk command:
awk -F '|' 'NF>3 {
match($3, "B[0-9]{1,3}([CG])[0-9]{1,9}", plan);
match($4, "R[0-9]{1,2}[DS]([CG])[0-9]{1,3}\\.myfqdn\\.com", server);
match($2, "[a-zA-Z0-9 -.]{1,99}", server_name);
if (plan[1] != server[1])
print "wrong server ==> plan:", plan[0] ",", "server:", server[0] ", server_name:" server_name[0]
}' data.txt
This is current output when I run (it is expected and fine):
wrong server ==> plan: B20C120, server: R1SG7.myfqdn.com, server_name: hostname1
wrong server ==> plan: B40G66, server: R1DC8.myfqdn.com, server_name: another-host-name
wrong server ==> plan: B400C88, server: R1DG10.myfqdn.com, server_name: last.mydomain.com
The logic of the above txt and awk is:
Plan names have either C or G in their name (after B, B is always the first letter), and server names after R1S or R1D, have either C or G.
For example if Plan is B20C120 and the server is R1SG7, then since C and G don’t match, then it’s a wrong plan server.
But B180G22 is in R1SG8 and that’s correct.
My current awk command has this issue in my mind:
- The
serveris is printed but I have to write a regex.
I tried this in my awk:
match($2, server_name);
but got this error:
awk: cmd. line:6: (FILENAME=data.txt FNR=4) fatal: attempt to use scalar `server_name' as an array
Also tried this:
match($2, "(.*)", server_name);
but for this, I got the current output with the above line.
Expected
is to make the server_name better.
>Solution :
You may use this awk:
cat parse.awk
BEGIN {
FS = "[[:blank:]]*\\|[[:blank:]]*"
}
NF>3 {
server_name = $2
match($3, /^B[0-9]{1,3}([CG])[0-9]{1,9}$/, plan);
match($4, /^R[0-9]{1,2}[DS]([CG])[0-9]{1,3}\.myfqdn\.com$/, server);
if (plan[1] != server[1])
print "wrong server ==> plan:", plan[0] ",", "server:", server[0] ", server_name:", server_name
}
Then use it as:
awk -f parse.awk file
wrong server ==> plan: B20C120, server: R1SG7.myfqdn.com, server_name: hostname1
wrong server ==> plan: B40G66, server: R1DC8.myfqdn.com, server_name: another-host-name
wrong server ==> plan: B400C88, server: R1DG10.myfqdn.com, server_name: last.mydomain.com
Details:
FS = "[[:blank:]]*\\|[[:blank:]]*"setsFSas|surrounded by optional spaces on both sides- Used regex literals
/.../instead of string as regex. - For more precise & correct matching used anchors
^and$in regex. - Now with the correct
FSwe don’t need to use any regex to setserver_name, just$2assignment is good enough
To use this directly from bash command line use:
awk '
BEGIN {
FS = "[[:blank:]]*\\|[[:blank:]]*"
}
NF>3 {
server_name = $2
match($3, /^B[0-9]{1,3}([CG])[0-9]{1,9}$/, plan);
match($4, /^R[0-9]{1,2}[DS]([CG])[0-9]{1,3}\.myfqdn\.com$/, server);
if (plan[1] != server[1])
print "wrong server ==> plan:", plan[0] ",", "server:", server[0] ", server_name:", server_name
}' file