Joining multiline records in (n)awk

I like awk (In Solaris, I like nawk better than awk, though 😉 ).
Let’s see how we can deal with multiline records. Here’s an approach I use quite often (if you have a better idea, please tell me!).

Given the following output of:

$ su - demo -c "prctl -t privileged -n project.max-shm-memory -i project user.demo"

which is for example:

Sun Microsystems Inc.   SunOS 5.10      Generic January 2005
project: 100: user.demo
NAME    PRIVILEGE       VALUE    FLAG   ACTION                       RECIPIENT
project.max-shm-memory
privileged      4.00GB      -   deny                                 -

I would like to have just one line with the most important fields:

project.max-shm-memory  4.00GB  deny

In order to get that, I search for the header line and print the interesting fields of the following lines:

$ su - demo -c "prctl -t privileged -n project.max-shm-memory -i project user.demo" | \
nawk '
{a++;if (a==-99){printf ("%s\t", $1)}}
/NAME/{a=-100}
/privileged/{printf ("%s\t%s\n", $2, $4)}'

By setting the counter a to -100 instead of a positive value, I do not have to initialize it in a BEGIN statement. For each line, I increase counter a. If it reaches -99 which is the next line after the line containing pattern NAME, I print the first field with just a tab but no newline. For the line that contains string privileged, I print column 2 and 4, plus the newline.

As the script does not select lines by just counting from the beginning, this is a very robust solution that works indepentendly of any “garbage” output caused by login scripts of the user I am using.

2 Responses to “Joining multiline records in (n)awk”

  1. Edward Berner Says:

    Looks like prctl has a “-P” option (on Solaris 10, at least) that displays the output in delimited format, which might be easier to deal with in awk or might already be in the format you want.

    However, assuming awk, here’s my take on it:

    prctl -t privileged -i task $(ps -o taskid= -p $$) \
    | nawk '/NAME/ {s=1;next} s==1 {printf("%s\t", $1);s=2;next}  s==2 {print $0;s=1;next}'
    
  2. Bernd Finger Says:

    Thanks, Edward!My problem is that I like (n)awk so much that I sometimes forget reading through all the output options of a command ;-)The “next” nawk option is just great. Haven’t used it before, but I will surely do soon. Thanks again!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s


%d bloggers like this: