Useful Shell Commands

Here is a list a few useful shell commands that problem solvers working on unix like machines.

Diff
If you learn nothing else, learn to use the command [Diff]. Diff compares two files and shows the differences between the files. It can save you endless frustration with wrong answers. It is especially helpful when you are making trivial formatting mistakes that you are overlooking. You are busy searching for logic errors deep in nested code, while it is extremely easy for a machine to find that you are not capitalizing the first character of the output.

For example, if you have a file input, containing sample input, a file output.correct containing the correct output for a given sample input, and a binary named a.out, then this sequence will show that your program is correct on the sample input.

$ ./a.out actual.output $ diff actual.output output.correct

Since diff gave no output, there were no differences between the files, and hence program ran correctly on the sample input.

Useful flags to diff are
 * -b - ignore whitespace differences, good for when you don't care about getting a presentation error
 * -u - unified diff format, a bit more readable output

Seq
Seq is a very simple command which generates numbers in sequence. This is a nice way of generating large input sets for numeric problems. For example. $ seq 1 5 1 2 3 4 5

Note that sometimes problems also call for some "header" information, like the number of inputs. This can be done by using an echo before the call to seq.

$ (echo 5 ; seq 1 5) > input_with_header $ cat input_with_header 5 1 2 3 4 5

The biggest problem with seq is that it is so simple that it cannot do things like generate pairs of numbers by itself.

Time
Are you getting Time Limit Exceeded errors? The easiest way to see how much your optimizations improved things is to use the time command. Just prepend "time" to the ordinary command that you were running and you will get a summary of where your program spends it's time.

$ time ./slow < big.input > slow_out

real   2m28.598s user   2m5.170s sys    0m0.420s

$ time ./a.out < big.input > fast_out

real   2m9.713s user   2m5.260s sys    0m0.238s

Sort
Yes, you know eighteen sorting algorithms, but it can be a pain to actually write a script that reads in lines or numbers from a file, sorts them, then spits them back out (especially the twentieth time around). Try the sort utility. By default it sorts strings.

$ echo -e "algorithmist\nTopCoder\nSPOJ" | sort SPOJ TopCoder algorithmist

$ echo -e "1\n1e9\n100\n2\n1000" | sort 1 100 1000 1e9 2

Of course, you probably don't want to sort numbers as strings, so use the -g (or -n) switch:

$ echo -e "1\n1e9\n100\n2\n1000" | sort -n 1 1e9 2 100 1000

$ echo -e "1\n1e9\n100\n2\n1000" | sort -g 1 2 100 1000 1e9