Printing column headers from commands
Thursday, March 22nd, 2012As with most things in *nix world there are more than one way of doing things. Here is a nifty trick I picked up from a former coworker. Sometimes when I needed to do disk reporting it was handy to have the column header (remember this is my use case) for those who don’t necessarily know what the columns mean when doing a df or similar and grepping for a particular volume / disk (read upper management). I am fairly certain that there are even more ways of accomplishing this, but here are two that I’ve used. Also be aware, that you need to know what you’re looking for, or the pattern you need to match.
Note: this was done from my MBP, so in Linux ymmv*.
sed:
Before: df -h | grep disk /dev/disk0s2 465Gi 123Gi 342Gi 27% / /dev/disk1s2 110Mi 94Mi 16Mi 86% /Volumes/VirtualBox /dev/disk2s0s2 25Mi 22Mi 2.7Mi 90% /Volumes/VZAccess Manager After: df -h | sed -n '/^Filesystem/p;/disk/p' Filesystem Size Used Avail Capacity Mounted on /dev/disk0s2 465Gi 123Gi 342Gi 27% / /dev/disk1s2 110Mi 94Mi 16Mi 86% /Volumes/VirtualBox /dev/disk2s0s2 25Mi 22Mi 2.7Mi 90% /Volumes/VZAccess Manager
awk:
Before: df -h | grep disk /dev/disk0s2 465Gi 123Gi 342Gi 27% / /dev/disk1s2 110Mi 94Mi 16Mi 86% /Volumes/VirtualBox /dev/disk2s0s2 25Mi 22Mi 2.7Mi 90% /Volumes/VZAccess Manager After: df -h | awk '/^Filesystem {print;}; /disk/ {print;}; {next;};' Filesystem Size Used Avail Capacity Mounted on /dev/disk0s2 465Gi 123Gi 342Gi 27% / /dev/disk1s2 110Mi 94Mi 16Mi 86% /Volumes/VirtualBox /dev/disk2s0s2 25Mi 22Mi 2.7Mi 90% /Volumes/VZAccess Manager
sed breakdown:
With the sed line we are matching any line that begins with Filesystem “/^Filesystem” and printing it “/p”, then matching any line that has disk “/disk” and printing it “/p”. The “-n” option to sed tells it to only print what we are looking for – from the sed manpage on OSX – “-n By default, each line of input is echoed to the standard output after all of the commands have been applied to it. The -n option suppresses this behavior.” If you were to remove the “-n” switch it would look something like this:
df -h | sed '/^Filesystem/p;/disk/p' Filesystem Size Used Avail Capacity Mounted on Filesystem Size Used Avail Capacity Mounted on /dev/disk0s2 465Gi 123Gi 342Gi 27% / /dev/disk0s2 465Gi 123Gi 342Gi 27% / devfs 199Ki 199Ki 0Bi 100% /dev map -hosts 0Bi 0Bi 0Bi 100% /net map auto_home 0Bi 0Bi 0Bi 100% /home /dev/disk1s2 110Mi 94Mi 16Mi 86% /Volumes/VirtualBox /dev/disk1s2 110Mi 94Mi 16Mi 86% /Volumes/VirtualBox /dev/disk2s0s2 25Mi 22Mi 2.7Mi 90% /Volumes/VZAccess Manager /dev/disk2s0s2 25Mi 22Mi 2.7Mi 90% /Volumes/VZAccess Manager
printing the matches multiple times due to matching on the “/^Filesystem” and matching on the “/disk”.
awk breakdown:
With the awk one, we are matching the line that begins with “/^Filesystem” and printing it, then matching the line with “/disk/” and printing, then followed by a statement “{next;}” to keep processing and skip unless the pattern matches.
Also while writing the post, thought of another one that it might be useful, though it really depends on what you’re running on your system. Thought of a little netstat example though I will go with the caveat here that netstat can easily make this a moot point, take this with a grain of salt.
Before: netstat -anl | grep -i listen tcp46 0 0 *.9292 *.* LISTEN tcp46 0 0 *.9302 *.* LISTEN tcp46 0 0 *.9301 *.* LISTEN tcp46 0 0 *.9200 *.* LISTEN tcp46 0 0 *.9300 *.* LISTEN tcp46 0 0 *.62056 *.* LISTEN tcp4 0 0 *.62056 *.* LISTEN tcp4 0 0 127.0.0.1.51093 *.* LISTEN tcp4 0 0 127.0.0.1.26164 *.* LISTEN tcp4 0 0 *.17500 *.* LISTEN tcp4 0 0 127.0.0.1.631 *.* LISTEN tcp6 0 0 ::1.631 *.* LISTEN ffffff80147a27d0 stream 0 0 ffffff8017e13f00 0 0 0 /tmp/launch-H5oHbg/Listeners After: netstat -anl | sed -n '/^Proto/p;/LISTEN/p' Proto Recv-Q Send-Q Local Address Foreign Address (state) tcp46 0 0 *.9292 *.* LISTEN tcp46 0 0 *.9302 *.* LISTEN tcp46 0 0 *.9301 *.* LISTEN tcp46 0 0 *.9200 *.* LISTEN tcp46 0 0 *.9300 *.* LISTEN tcp46 0 0 *.62056 *.* LISTEN tcp4 0 0 *.62056 *.* LISTEN tcp4 0 0 127.0.0.1.51093 *.* LISTEN tcp4 0 0 127.0.0.1.26164 *.* LISTEN tcp4 0 0 *.17500 *.* LISTEN tcp4 0 0 127.0.0.1.631 *.* LISTEN tcp6 0 0 ::1.631 *.* LISTEN
Again, this makes the presumption that you know what you’re looking for, and if you tried to do that with ESTABLISHED in netstat it may be moot unless you narrowed down to less than a screen. Also I’ll leave the awk version and looking for specific ports / port ranges as an exercise for the reader. Also astute readers will notice that we lost the last output from the first netstat command due to not grepping indiscriminately.
I hope this information comes in handy, share and enjoy!
*For those that may not know, ymmv = Your Mileage May Vary.
