Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

awk how to print whole column if match

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):

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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:

  1. The server is 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:]]*" sets FS as | 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 FS we don’t need to use any regex to set server_name, just $2 assignment 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
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading