I saved grep for last because grep deserves the attention. grep is one of those tools that probably deserves its own spot in history, like sed or rsync. It’s just that powerful.
You probably know what grep does — screens through streams of text and spits out matching results. So at its most basic,
grep Text file.txt
should highlight lines in file.txt that match “Text” … simple, isn’t it?
grep makes it simple, that’s for sure. Have three files and you’re not sure where something is?
grep Text file-01.txt file-02.txt file-03.txt
grep finds it, adding the name of the file on the front, whenever “Text” appeared.
So what else can grep handle? How about numbering results, so I don’t have to pick through lines by hand?
grep -n Text file.txt
Yes, numbers! But wait, the numbers are the lines “Text” appears in, not the number in the list. Keep that in mind.
There’s another option that might not seem valuable. Here’s the
-o flag, which plays havoc on my test file.
grep -o ie test.txt
Output looks like this:
ie ie ie ie
Well that’s dumb. Or not. Here’s the same thing with the line numbering option:
grep -on ie test.txt
And you get:
36:ie 54:ie 97:ie 100:ie
So sometimes, for example on long lines of text, maybe I don’t care about the actual output, only the line it appears on. Easier to find typos, I should think.
What’s next … how about
-C. A will show lines after the matching string, B shows before the string, and C is sort of a combination of A and B. Ergo,
grep -A2 ie test.txt
coefficients guildhall customs -- energies slurring benight -- ladies infringements meets metier
Note that the second and third lines in each set there don’t necessarily contain the “ie” pair, but I asked that they be included. grep adds the double dashes.
And that last line, “metier”? Where’s its following couple? Nowhere. That’s the end of the file, and it’s only three lines after the word “ladies,” so it appears to be a string of four.
Probably the most important flag is
-v for the simple reason that it reverses the results — instead of finding matches, grep reports nonmatching lines. To wit:
grep -vn e test.txt
And the results include …
78:bursty 82:lobby 83:harrows 85:skulk 91:propyl 93:cowling 94:tracy 95:unflagging
And so forth, with no letter “e” in a line.
grep comes into play a lot more than I would think. The Index page for this site is built off a massive XML export, and I need grep to skim through it all and find the links.
Or, here’s a list of movies, skimmed to find anything from the 1940s.
grep 194 list-01.txt
Fantasia (1940) It's a Wonderful Life (1946) Notorious (1946) The First of the Few (1942) The Great Dictator (1940)
Try piping directory lists through grep; it might be easier to handle than
ls at times. I’ve seen other sites that use grep in conjunction with find as a kind of screen that displays directory paths. Clever.
I should mention that grep comes with
fgrep, the former handling regular expressions more deftly than the
-E flag for regular grep. The latter is a “faster” grep, and might be more useful for those really, really big searches.
One more flag, and I’m done. You guessed it:
Nothing is complete without color. 😉