Of Grep and Finding Stuff
I can make a safe assumption that 90% of the people reading this blog know how to use grep, at least on a basic level. But what about those of us who don’t? Here’s a quick look into grep and grep in Emacs specifically. Before we dive in there’s a bit of a realization I want to expend on in the footnotes though1.
The classic scenario: use Dired to get into a directory, and then use grep and its various siblings to search for a text pattern in all the files in that directory.
M-x grep will automatically call
grep --color -nH --null -e. This works with the syntax like so:
grep --color -nH --null -e "<pattern to match>" <file pattern>.
For example, I can search for “burger” in a folder with old org files that are no longer indexed in org-agenda2 by calling grep and using it like so:
grep --color -nH --null -e "burger" *.org. This will give me a list of all the files along with a blurb of text (showing the results in context) with the word burger highlighted.
This command also works for two terms, in the form of term1 or term2, like so:
grep --color -nH -e "burger" -e "restaurant" *org. It will show us burger or restaurant, but not burger and restaurant. So if I want to search for restaurants that served me with a juicy burger some years back, I’m out of luck: grep will bring up all occurrences of restaurants and /all occurrences of burger.
In shell, we can pipe one grep into another:
grep burger *.org | grep restaurant is all that’s needed to give us basic results. In Emacs, however, we can’t pipe grep like we do in shell3. We can call shell in Emacs (with
M-!) and execute this in the folder we’re in, or just run Shell from inside Emacs, but there are quicker ways.
M-s O)4 will search for regex strings in the active buffer on the screen by default. This means that if you just preformed a grep search and got results for one term, I can use Occur on the results for the second term.
To use the example above, I will first call
grep --color -nH --null -e "restaurant" *.org, and then use Occur on the results to look for “burger” (without the quotations). Since I use Swiper, part of Abo-abo’s must-have Ivy package, I could run a simple search (
C-s) on those results and apply another filter, like “black bean5” because I barely eat any meat burgers anymore. I rarely need to apply a third filter like, and if I ever need to apply a fourth, it’s probably better to just change my search tragedy.
This post and much of what I’ve learned about grep in Emacs is thanks to the awesome folks over at Mastodon. Check the original thread here.
After going over this post, I realize it starts somewhere in the middle. There are people who don’t know what grep is, and, lacking the right questions to find information about it, they will have hard time learning about this command. Consider, for example, a person who’s coming from their Mac’s spotlight feature which indexes everything for them. It’s a stretch enough for them to use the terminal, but even then, what are they actually looking for? The terms “Words” and “text” are so rudimentary to us that they might omit searching for those. A user who’s new to Linux might search for “how to find stuff in Linux” or “how to find documents” or “how to find what I wrote” before they search for “how to find text in Linux,” which is still a bit of a stretch.
The Emacs manual throws this question back at the user: “Just as you can run a compiler from Emacs and then visit the lines where there were compilation errors, you can also run grep and then visit the lines on which matches were found. This works by treating the matches reported by grep as if they were “errors."” What does that even mean?
I look at my post now, and I think, I know this today, I know what to ask today, how would I know to ask this not even 5 years ago? Where do I even start? ↩︎
For those who don’t use org-mode: org-mode comes with a powerful built-in “search engine”, the agenda. It loads a list of folder and files when Emacs starts, so you can execute various function on them like scheduling tasks or assign tags. The agenda dispatcher comes with powerful search options that let you search by date, keyword, tags, etc. ↩︎
I’m still learning more about this, and I’m not sure why, but I think it’s because the
|character is not a special character in Emacs, so grep grabs it literally and looks for the pipe character in the text. ↩︎
Occur has its on various siblings in Emacs and can be largely used in the same exact way as grep, though there are differences. It’s worth taking a look if you’re not familiar with it. ↩︎
This double space is not a mistake. In Swiper search, double space is how you ask to look for space. ↩︎