cat is a tool to read data from standard input or a file and emit it on standard output. That sounds simple – and it is – but it has some very useful applications; not least, reading a file straight to the current terminal for inspection without any other tools.
But this simplicity and utility also leads to many uses of
cat which aren’t necessary and in fact add some (minor) processing overhead. Some Unix fans are so upset by “useless uses of cat” that they have founded an award in its honour.
Let’s take a look at some common and useless uses of
cat, and how they can be replaced by shell built-ins instead.
cat | grep: search within file
Reading a file for standard input into another tool is very common. This example could be used as follows:
cat myfile.txt | grep "adventure"
In this example, cat reads the file myfile.txt and passes its contents to grep for searching. However, grep can read the file itself and that saves an additional process and a pipeline:
grep "adventure" myfile.txt
cat | mysql: send a file to standard input
A common operation is to read a file of SQL instructions (such as a backup) from disk, and pass it to the mysql command for execution:
cat mytable.sql | mysql -h localhost -u root -p
POSIX-compatible shells, including bash, can read the file onto standard input and save an additional process and a pipeline:
mysql -h localhost -u root -p < mytable.sql
If you have a longer pipeline and it makes sense to think about data flow from left to right, it’s even possible to place the standard input at the beginning of the pipeline:
< mytable.sql | grep -v "DROP" | mysql -h localhost -u root -p
cat | sed: retrieve a set range of lines from a file
Fetching a pre-defined set of lines from a file is easy with
cat mygiantfile.txt | sed -n '16224,16482p;16483q'
You can probably see where this is going; sed can read the file itself:
sed -n '16224,16482p;16483q' mygiantfile.txt
What’s different here though is that mygiantfile.txt is very large, and so to send it all into sed’s standard input only to discard most of it is very inefficient. Allowing sed to read the file itself means it can do efficient seeking on the file and not read it all into memory first!
Legitimate use of
There are times when cat is very useful for making basic changes to the input stream, as the manual suggests:
-b, --number-nonblank number nonempty output lines, overrides -n -E, --show-ends display $ at end of each line -n, --number number all output lines -s, --squeeze-blank suppress repeated empty output lines -t equivalent to -vT -T, --show-tabs display TAB characters as ^I -v, --show-nonprinting use ^ and M- notation, except for LFD and TAB
It’s also sometimes necessary to read multiple input files sequentially and provide them all in one standard input, for example when constructing TLS certificate chains:
cat privkey.pem cert.pem ca.pem > fullchain.pem