Narrowing Search Results

Sometimes I know the keywords to search for, but there are too many files on my drive to wade through. That's when I turn to mdfind's handy -onlyin option. It restricts the files returned to files in a specific directory, and the directories below it. This may also speed up searching significantly, since mdfind only has to search a small part of its index for my files.

If I know my invoice is probably somewhere in my home directory's subdirectory called writing, I can use

$ mdfind -onlyin /Users/alester/writing invoice

or, using the tilde character to tell the shell to expand to my home directory, shorten it as

$ mdfind -onlyin ~/writing invoice

I can have multiple -onlyin options, so if I have a folder of stuff I've been meaning to file away, I can include that in my search with:

Note that because of the spaces in /Users/alester/to be filed I must put the pathname in double quotes. This also means I can't use the tilde shortcut, because the tilde is a shell character that won't be expanded in quotes.

Unfortunately, mdfind doesn't understand the period to mean "the current directory," but I can use the special shell variable $PWD instead:

$ cd ~/Music/iTunes
$ mdfind -onlyin $PWD "East Bound And Down"

Filtering mdfind's output

Another way to narrow the number of hits is to analyze the output of mdfind. Unix has many programs called filters that take output from one program, analyze or modify it, and create a different set of output.

One of the most common filters is the grep command, which searches a set of input for lines that match a given pattern. In this case, I want grep to show me only lines that have the word "Perl" in them somewhere:

$ mdfind invoice | grep Perl
$

That didn't return the results I want. I'll try it again with the -i flag to tell grep to do case-insensitive matching.

Now I've found the results I wanted. I could have rerun it with grep perl, but then I would have missed results that might have been spelled "Perl".

A downside of this technique is that it only searches the file and directory name. Even though both of these books I worked on were for Apress, if I'd tried to grep on "Apress", I'd have come up empty, because "Apress" doesn't appear in any of the file or directory names.

$ mdfind invoice | grep -i apress
$

Another useful grep option is -v. It tells grep to show only lines that do not match the expression. For example, if I want to exclude all the results from my IMAP Mail account, I can use

$ mdfind invoice | grep -v IMAP

and I won't see any results where "IMAP" appears in the filename or directory. This can be dangerous, since if I've invoiced the mythical HandiMap company and saved it as /Users/alester/HANDIMAP/invoice-2005.doc, it will be excluded from the results, too.

Another handy Unix tool is the program wc. wc stands for "word count," but with the -l flag it shows me the number of lines in the input passed to it.

$ mdfind invoice | wc -l
110

Here I find that mdfind returned 110 files matching "invoice". Surely you didn't think I would have counted all 110 file matches at the beginning of this section by hand, did you?