Awk command is one of the most useful unix tools and yet the most (in my view) underrated. It can save you a lot of efforts writing any code. Everyone uses a lot of grep in conjunction with programming but awk can do more than grep in some cases.
Here are some very simple examples of grep with awk running on Linux:
Get the value from the name=value pair:
grep ‘<name>=’ | awk -F= ‘print {$2}’
Get the IP address of an ethernet port:
ifconfig eth1 | grep ‘inet addr’ | awk ‘{print substr($2, 6)}’
These awk examples extract the target string directly. When combines with languages like C or Php, simply calls fgets function to read the desired string. No extra code is needed for parsing the line format.
Awk with pattern
Here is a slightly more complicated example showing how awk can be further utilised without the help of grep.
For instance, we want to get a list of mount points from devices with write permission. Following is the mount command output. (I have trimmed the output, so it nicely fits in this blog).
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
tmpfs on /dev/shm type tmpfs (rw)
devpts on /dev/pts type devpts (rw,mode=0620,gid=5)
/dev/hda on /media/dvd type subfs (ro,nosuid,nodev,fs=cdfss,procuid,…)
usbfs on /proc/bus/usb type usbfs (rw)
/dev/sdb1 on /media/usb-01 type subfs (rw,noexec,nosuid,nodev,….)
/dev/sdc1 on /media/usb-02 type subfs (rw,noexec,nosuid,nodev,…..)
From the list above, I need to extract lines with /dev/ and also ‘rw’ in the mount options list. You can try grep ‘<rw>’ | grep ‘^/dev/’ to get the lines that you desire. However, this doesn’t guarantee the location of ‘rw‘ in the line, it can be coincidently a mount directory called ‘rw’. Nonetheless, you still have to write extra code to parse the lines format.
With awk, you can simply do that
mount | grep ‘^/dev/’ | awk ‘{ if (match($6, /<rw>/)) print $3; }’
It parses the results and outputs this. It’s all done for you.
/
/media/usb-01
/media/usb-02
However, awk is even better. It can (should always) be also used as:
awk ‘/pattern/ { actions }’
whereas the pattern part can save us using the grep command. Here is another example using the pattern instead of grep:
mount | awk ‘/^/dev// { if (match($6, /<rw>/)) print $3; }’
If you want to target specific devices such as /dev/sd* and /dev/hd*, you can do:
mount | awk ‘/^/dev/[s|h]d/ { if (match($6, /<rw>/)) print $3; }’
There are lots more you can achieve with awk. It depends on how your imagination and will to solve a problem.
You may argue that it takes too long to write a simple awk script compared to your programming language. It is only because you may not familiar with awk. Use it more often, explore a bit more every time when you use it. Then awk will reward you by saving you writing less code when you need it next time.
Less code, less bugs.
I work for iTrinegy and here are my other technical blogs

1 response so far ↓
Zero Signal // March 6, 2009 at 4:29 pm |
I love awk. It is pretty easy to learn and it is quite powerful.