2008-02-07

UNIX tip of the day: More awk recipes

Awk, as we have mentioned before, is a ridiculously handy utility that often goes under-appreciated by systems administrators and UNIX geeks alike.

A few days ago, a colleague of mine told me about some complex awk magic that he'd implemented in order to acquire not only the matching line of an input stream (in this case, a log file), but the two lines prior to that matching line which contained some useful information as to what was going on. It was an elaborate solution that worked well, but I swooped in with a much simpler recipe to do the same thing. This prints the two lines prior to the matching expression as well as the line containing the expression. Certain incarnations of grep can do the same thing, but this way you can also format the lines if you know your awk-fu.

$ awk '/some-regex/{print two "\n" one "\n" $0};{two=one};{one=$0}' /some/file.log

I actually keep a bunch of handy commands and UNIX tips written down. These are things that I know I won't need to use very frequently, but know I'll eventually need again.

I'll share some more awk magic with you from within its pages.

Get only the last field of a line that matches a regex:
$ awk '/some-regex/{print $NF}' /some/file

This works because NF contains the number of fields found in the line. $NF, then, contains the value of that last field. Just like $1 would contain the value of the first, if NF is 5, $NF would have the value of the 5th (and last) field. I love this one.

Example:
I'll set the field separator to a / and use awk to get only the last entry from the directory structure with find:

Raw find output:
$ find .
.
./.localized
./images
./images/apache_pb.gif
./images/gradient.jpg
./images/macosxlogo.png
./images/web_share.gif
./index.html


Now with awk:
$ find . | awk -F/ '/images/{print $NF}'
images
apache_pb.gif
gradient.jpg
macosxlogo.png
web_share.gif


If you're into AIX, a lot of the configuration files are in "Stanza" format. That is, a label, followed by a bunch of data and then a blank line between records. Awk can get just the one stanza you want from a stanza file. Example here is the /etc/security/user file on AIX, which tracks security profile information for every user on the system. The "default" stanza is an important one, as anything within it gets propagated to all users first, then any deviations from the default happen in the users' own stanzas:
# awk '/^default/,/^$/ {print}' /etc/security/user

Truth be told, stanza format and some of its variants are popular in other operating systems, but this particular awk recipe works best on AIX.

Have any awk-fu? Let's see some of your favorites. The comments are open!

blog comments powered by Disqus