Never write it in ‘C’ if you can do it in ‘awk’; Never do it in ‘awk’ if ‘sed’ can handle it; Never use ‘sed’ when ‘tr’ can do the job; Never invoke ‘tr’ when ‘cat’ is sufficient; Avoid using ‘cat’ whenever possible.
–Taylor’s Laws of Programming
Last month, we looked at loops and conditional execution. This time around, we’ll look at a few of the simpler « external » tools (i.e., GNU utilities) that are commonly used in shell scripts.
Something to keep in mind as you read this article: the tools available to you as a script writer, as you might have guessed from the above quote, are arranged in a rough sort of a « power hierarchy ». It’s important to remember this – if you find yourself continually being frustrated by the limitations of a specific tool, it may not have enough « juice » to do the job.
Some time ago, while writing a script that processed Clipper database files, I found myself pushed up against the wall by the limitations of arrays in « bash »; after a day and a half of fighting it, I swore a bitter oath, glued a « screw it » label over the original attempt, and rewrote it in « awk ».
It took 15 minutes.
I didn’t tell anyone at the time; even my good friends would have taken a « clue-by-4 » to my head to make sure that the lesson stuck…
Don’t be stubborn about changing tools when the original one proves under-powered.
Strange as it may seem, ‘cat’ – which you’ve probably used on innumerable occasions – can do a number of useful things beyond simple catenation. As an example, ‘cat -v file.txt’ will print the contents of « file.txt » to the screen – and will also show you all the non-text characters that might normally be invisible (this excludes the standard textfile characters such as `end-of-line’ and `tab’), in « ‘^’ notation ». This can be very useful when you’ve got something that is supposed to be a text file, but various utilities keep failing to process it and give errors like « This is a binary file! ». This capability can also come in handy when converting files from one type to another (see the section on ‘tr’). If you decide you’d like to see all the characters in the file, the `-A’ switch will fill the bill – `$’ signs will show the end-of-lines (the buck stops here?), and `^I’ will show the tabs.
‘-n’ is another useful option. This one will number all the lines (you can use `-b’ to number only the non-blank lines) of a file – very useful when you want to create a `line selector’, i.e., whenever you want to have a « handle » for a specific line which you would then pass to another utility, say, ‘sed’ (which is very happy with line numbers).
‘cat’ can also serve as a « mini-editor », if you need to insert more than a line or two into a file during the execution of your script. In most cases, the built-in ‘read’ function of ‘bash’ will take care of that sort of thing – but it is designed as more of a « question/reply » mechanism; ‘cat’ is a bit more useful for file input.
Last, but not least, ‘cat’ is very useful for displaying formatted text, e.g., the error messages at the beginning of a shell script.
Here are two script « snippets » for comparison:
echo « ‘guess’ – a shell script that reads your mind »
echo « and runs the program you’re thinking about. »
echo « Syntax: »
echo « guess [-fnrs] »
echo « -f Force mode: if no mental activity is detected, »
echo » take a Scientific Wild-Ass Guess (SWAG) and execute. »
echo « -n Read your neighbor’s mind; commonly used to retrieve »
echo » the URLs of really good porno sites. »
echo « -r Reboot brain via TCP (Telepathic Control Protocol) – for
echo » those times when you’re drawing a complete blank. »
echo « -s Read the supervisor’s mind; implies the ‘-f’ option. »