Earlier I wrote about using Unix command line tools to manage text when the job at hand calls for a quick fix instead of a program that you plan to keep around. When the script that I’m writing is a longer one I will often reach for ruby, but ruby can also be quite useful for quick scripts. Specifically, the ruby executable provides several command line flags that are helpful when writing these quick scripts.
-e is the first flag we’ll need for using ruby as our command line swiss army knife. If you call ruby with
-e it will evaluate the string following it with the ruby interpreter. Example:
ruby -e 'puts "Hello, world!"'
Got it? Good, now lets move on to more interesting options.
-n, -p, and -i
-n flag causes ruby to loop over each line of the input. For example if you want to capitalize all of the lines in a file (to stdout) you could do the following:
ruby -n -e 'puts $_.upcase' < original-file.txt > upcased-file.txt
Printing out something is so common that ruby provides another flag that will print out the value of
$_ after each step. With -p the following example becomes:
ruby -p -e '$_.upcase!' < original-file.txt > upcased-file.txt
Notice that we are now using the destructive version of
upcase!) so that the value of
$_ is redefined before it is printed out. It turns out that taking a file, performing some operation on each line, printing the changed line and then putting in a new file is so common that ruby gives us yet another flag to help with this occasion. We can shorten our simple example even further with
ruby -p -i -e '$_.upcase!' file.txt
-i flag tells ruby to operate on the passed file in-place. This means rather than redirect the file into ruby and the output out of ruby, it will open the file itself and overwrite it with the modified lines. Obviously this isn’t quite the same result as the earlier examples in that the original file is no longer maintained. If you don’t want to lose the original (or you aren’t confident that your script is going to work as expected) you can pass
-i a backup extension to make a copy of the original file.
You’ll notice this is similar to the
-i flag of sed. I find myself using ruby with
-i now whenever I might reach for sed because the
-i flag of sed seems to work differently in Linux than in the BSD tools. With ruby I don’t have to worry about the cross-platform stuff as much.
Dave Thomas (of the Pragmatic Programmers) put together a list of handy one liners for ruby. This is old but still quite useful:
And, as always, the man page has a lot of great information.