As any Unix veteran will tell you, the
cat utility is much abused. Here’s the common scenario:
Of course, this kind of abuse isn’t limited to the “pipe to grep” variety. Here’s the general form:
Indeed, flaming other Unix users for the Useless Use of Cat has long been the ‘national sport’ of the Unix tribe, since Usenet days.
What’s wrong with this pattern?
One thing, certainly. Two things, probably.
cat is meant to concatenate two or more files together
If you are using
cat with only one filename argument, then by definition you aren’t concatenating anything.
So, here’s the proper use of
2. many commands accept STDIN, but prefer a filename argument
This falls into a related anti-pattern of “Useless Use of Pipe”. Instead of:
Why is this such a common anti-pattern?
I still find myself occasionally falling into this pattern, despite two decades’ worth of keyboard time on Unix variants. I think this habit likely persists for two reasons:
1. The habit is learned early
Early bad habits are often hard to break. One of the first things a CLI user wants to do is to read a file, and until the use of pager commands becomes second nature, this will likely lead to:
For small ASCII files, this may even be an appropriate use of
cat. Usually though, this early habit leads to a second, more subtle, and persistent mental model.
cat is a conceptual pipeline source
When building up a complex filter, often
cat starts things off:
The thought process behind this command is: start with some text, then filter it thus, and filter it so, then write it to an output file. Simple. In some cases, I even give myself a pass on this if it makes my intention clearer. Usually, though, I try to fix the habit.
Refactoring. No, really. More on this next time.
Bonus: Useless use of
Often I will do the following to get a matching pattern count:
So, first let’s clean up the UUoP:
grep has a
-c flag, which displays the count of matched lines, so: