Working to Become a Unix/Linux Master Plumber

I've been reading an old but great book, The Unix Programming Environment (1984), by Brian Kernighan (of K&R C fame) and Rob Pike. I think it's no longer in print, because the price on Amazon for a new paperback is over $50. On Half.com you can find it for less than $10.

The book acts as a supplement to the UNIX manual, and is meant for beginners to the UNIX system. I've been using Linux since 2000, and I've learned a good bit along the way, but never really understood the environment, weird stuff like 1>&2 and sed/awk, and used only a little of what grep has to offer. I can pipe commands, tail logs and edit files, but I've never really used the command line as a programming tool. Boy, I was missing out!

Why do I say "master plumber" in the title? Why not ninja or something. Because command line programming is like plumbing, or an electrician, even. You're connecting the output of one component to the input of another, adding filters, transforming inputs, etc. I'm not great at analogies.

Take a look at this:

cat words.txt | tr -s [:blank:] '\012' |  
uniq -i | grep -P '^(.)(.)(.)\2\1$' |  
sort -f | head -5  

This little one-liner (it can fit on a line but I broke it up for readability), does the following:

  1. reads and outputs the content of words.txt, which is a file of dictionary words, separated by spaces: cat words.txt
  2. transliterates horizontal whitespace into newlines: tr -s [:blank:] '\012'
  3. removes duplicate lines, ignoring case: uniq -i
  4. looks for a 5-letter palindrome on each line: grep -P '^(.)(.)(.)\2\1'
  5. sorts the words, ignoring case: sort -f
  6. displays the first 5: head -5

The output for me:

civic  
dewed  
kayak  
level  
madam  

So this little shorty set of commands did a lot of work. Writing a Perl, PHP or Python script to do the same thing could be done easily, but it would be much longer and probably not nearly as efficient.

I'm only 108 pages in, but every page has something so useful, or explains a concept I wish I had known.

To continue my studies in this later, I'll be reading Linux Pocket Guide, 2nd Edition or The Linux Command Line: A Complete Introduction 1st Edition to make sure I have knowledge of Linux. Most of the UNIX goodies in the K&P book are still applicable, which is pretty amazing, but I need familiarity with modern *nix systems.

I've heard good things about Unix Power Tools, Third Edition 3rd Edition but its last printing was 2002. In computing terms, that was long ago.

The pick command, saved for posterity

Speaking of Unix Power Tools, one of the commands in the K&P UNIX book is the pick command. When piped with other commands, it will take its input one line at a time, and echo the line with a prompt, so you can answer y or n to each. You could have a special script that wraps rm and this command so that it will prompt before deleting each of a set of files. Very handy!

However, pick doesn't exist on Linux. I Googled around and found a Stack Overflow post that says it was just a little script used commonly on UNIX systems, but never added to the core set of commands.

The links were broken (as was my heart), so I used the Wayback Machine to find the original linked content. It turns out the source for the script is in Unix Power Tools :)

So saved from the dustbin of history, here's the pick command, updated for bash:

#!/bin/bash
# pick:  select arguments

PATH=/bin:/usr/bin

for i  
do  
    echo -n "$i? " >/dev/tty
    read response
    case $response in
    y*)    echo $i ;;
    q*)    break
    esac
done </dev/tty  

K&P UNIX also has the source for the pick command written in C, on page 187. It's a good bit longer.

Anyway, back to reading. Loving this!

comments powered by Disqus