Effective Command Line Searching

I do keep a fair amount of information inside text files - this is how I organize myself, keep track of what I've read, etc.

Occasionally, I need to search these files by content to retrieve some information, or remind myself of something I read earlier. Hence the need for software that does just that.

So far, I had settled on Agent Ransack on Windows and Tembo on OS X. However, I was looking for something a bit more snappy, hence the idea of using a command line tool.

I expect the reader will be familiar with the venerable grep, but it turns out there are a whole lot more tools that can be used.

The most useful resource I found online was this comparison of tools, which compares (at the time of writing), ack, ag, git-grep, GNU grep and rg.

After a glance, I was really tempted to use ripgrep (rg), which seems to be the fastest of the bunch, has well-rounded features and nice documentations.

However, it lacked a vital feature for me: multi-line matching. I store a lot of text formatted to hard-line-wrap at 80 characters, and I want to be able to search for word groups accros line boundaries. So ultimately I settled on the silver searcher (ag), which is great as well.

Effective Selecting

Additionally, I also wanted to try selecta, a command line tool by Gary Bernhardt.

What it does is read lines from the input stream and allow you to scroll these lines on the command line, ultimately selecting one. If this description is unclear, check the animated gif on the github page.

Unfortunately selecta is Unix-only, however there are a few clones and I ended up settling on the multi-platform heatseeker.

Here's an example of what I can do with ag and heatseeker (hs):

em $(ag -l parser | hs)

Or the Windows equivalent (assuming you have xargs installed, it comes with Cygwin, MinGW and even Git):

ag -l parser | hs | xargs em

What I'm doing is that I'm searching for the string "parser" in the current directory. The -l flag says to only print the file name (not the line number) of matches. Then heatseeker is used for the selection, and once the selection is done, the file opens in Emacs (em is my custom Emacs launching script).

Of course, this could be encapsulated in a batch script or bash function in order to be even more convenient.

Just to be clear, the article is about searching inside text files. However, I also often want to search files by name.

To do this, I use GUI programs. On Windows, the best is Everything. I have this handy program hotkeyed to Win+S and I use it all the time to quickly navigate to a file.

OS X has unfortunately nothing as good as that. The main problem is that most search programs seems to rely on the Spotlight engine, which is flaky in a couple of places. Most aggravating for me, Spotlight will not search inside dot-directories (e.g. .config). It's also not possible to formulate queries as easily as in Everything. I think partial path matching is not possible for instance. The search program that don't use the Spotlight engine are somehow even worse.

In the absence of a real solution, Tembo is also able to search on file names on OS X. It's not a patch on Everything, but it's better than nothing (accidental pun!).

In the rare cases where I want to search on the command line, I can either use the venerable find or the use -g flag of ag.

Android

I also have a bunch of text files synced on my phone, and on the rare occassion I need to make a search on the go, I use the aGrep application. I have also tried DocSearch, but the user experience was less pleasant.