
Grepping is awesome, as long as you don't glob it up! This article covers some grep and regex basics.
There are generally two types of coffee drinkers. The first type buys a can of pre-ground beans and uses the included scoop to make their automatic drip coffee in the morning. The second type picks single-origin beans from various parts of the world, accepts only beans that have been roasted within the past week and grinds those beans with a conical burr grinder moments before brewing in any number of complicated methods. Text searching is a bit like that.
For most things on the command line, people think of *.* or *.txt and are happy to use file globbing to select the files they want. When it comes to grepping a log file, however, you need to get a little fancier. The confusing part is when the syntax of globbing and regex overlap. Thankfully, it's not hard to figure out when to use which construct.
Globbing
The command shell uses globbing for filename completion. If you type
something like ls *.txt
, you'll get a list of all the files that end in
.txt in the current directory. If you do ls R*.txt
, you'll get all the
files that start with capital R and have the .txt extension. The asterisk
is a wild card that lets you quickly filter which files you mean.
You also can use a question mark in globbing if you want to specify a
single character. So, typing ls read??.txt
will list readme.txt, but not
read.txt. That's different from ls read*.txt
, which will match both
readme.txt and read.txt, because the asterisk means "zero or more
characters" in the file glob.
Here's the easy way to remember if you're using globbing (which is very simple) vs. regular expressions: globbing is done to filenames by the shell, and regex is used for searching text. The only frustrating exception to this is that sometimes the shell is too smart and conveniently does globbing when you don't want it to—for example:
grep file* README.TXT
In most cases, this will search the file README.TXT looking for the regular
expression file*
, which is what you normally want. But if there happens to
be a file in the current folder that matches the file*
glob (let's say
filename.txt), the shell will assume you meant to pass that to
grep
, and so
grep actually will see:
grep filename.txt README.TXT
Gee, thank you so much Mr. Shell, but that's not what I wanted to do. For
that reason, I recommend always using quotation marks when using
grep
. 99%
of the time you won't get an accidental glob match, but that 1% can be
infuriating. So when using grep
, this is much safer:
grep "file*" README.TXT
Because even if there is a filename.txt, the shell won't substitute it automatically.