Thursday, November 11, 2010

CLI - Vim and Awk

Vim and awk.  It is great to make a list, then modify that list and save it out.  These types of tools are why using any text editor on Linux is way more powerful than on the competition's operating system.  Just like with most solutions in Linux is that the tools are probably too many and do too much so the first steps are overwhelming with choices.

While a use case that doesn't happen every day here is the quick geek-mode of explaining a recent use I had.   Situation: home server runs dnsmasq (dns and dhcp server) for the home network.  I needed to ping assigned IP's for a monitoring script.  This is the geek-mode of explaining what I did.  With the resulting screenshot.

$vim fake-hosts   
This makes the new empty file.

:r !cat /etc/hosts

Fills the file with the current hosts file contents.  I've cleaned up comments and lines that won't change by using "dd" to delete the self referring IP's and lines that start with "#" since they aren't really IP addresses

%!awk '{print "ping "$1}'
This takes the IP column and prints it as the second column while creating a new first column with only the word 'ping' and notice that there is the space included inside the double quotes.

Remember, if you make a mistake with one of these that while in the CMD mode of vim the keyboard command "u" does undo just as you might expect it should. 

This process works differently than a search and replace where you need to change the subnet, it would make since to just do a search and replace of "168.0." -> "168.2." which would replace only that value.

This process works if you need to do transitive work on a text file that isn't a csv format.  Note that with this tool it is easy to take a list of results and make a csv with something like  %!awk '{print $1 ", " $2 ", " $3}'  and the 3 column file turns into a csv.  But wait, the original is correct, but in the wrong order, make your corrected csv with the following -> %!awk '{print $2 ", " $3 ", " $1}' with awesome results.

Play with it, have fun.

Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.


Félix-Antoine Fortin said...

Cool, but you can save yourself some keystrokes. The call to 'cat' is not useful since ':r' is and I cite man : ":r[ead] [++opt] [name] Insert the file [name] (default: current file) below the cursor." So you have just go with : ':r /etc/hosts'

Thought you might find that useful.

CafeNinja said...

You are totally correct. I was trying to display an example of recording the output of a command and could not think of any better example. But what you have written here is absolutely 100% correct. Thanks for the feedback.