mdfind: A Command-line Interface to macOS's Spotlight
This article is part of the “Meta Advent 2019” series. I’ve committed to writing a new blog post here every day until Christmas.
macOS’s Spotlight is an extremely powerful and fast search tool.
Its speed is derived from the fact that internally Spotlight relies
on a pre-built file database (similar to what the Unix utility locate
does).
While for most people using Spotlight’s GUI interface is probably fine, people like me
prefer to be able to leverage it from their terminals. Fortunately, that’s pretty
easy to do, as macOS ships with a command-line interface for Spotlight called mdfind
.1
Let’s play a bit with mdfind
to see how it can help us. I’ll share with you some of the ways
in which I normally use mdfind
. I encourage all of you to try the examples locally to get a
better feel for how the different commands works.
Here’s how you’d search for all files containing some text (you can think of this as some hybrid of grep
and find
):
$ mdfind cider
Here’s how you’d search for all files matching some name:
$ mdfind -name bozhidar.jpg
Note that this does a simple text match for the name, so you can easily expand the search by making it more generic:
$ mdfind -name bozhidar
You can also search for multiple words in the filename:
$ mdfind -name clojure mobi
You can easily limit the search to a particular directory like this:
$ mdfind -onlyin ~/Downloads -name bozhidar
Another way to limit a search is by specifying the type (kind) of the files to look for/in:
$ mdfind kind:image -name bozhidar
You can also do some fancier searches by matching for some specific macOS file metadata. The example bellow is searching for all files and folders named exactly “Clojure”:
$ mdfind "kMDItemFSName = Clojure"
Admittedly it’s not very easy to remember attribute names like this one, but the possibility this opens up are almost
endless. To get an idea about the metadata attributes that exist you can check them for some file with the
mdls
command:
$ mdls index.md
kMDItemContentCreationDate = 2018-10-27 06:08:22 +0000
kMDItemContentCreationDate_Ranking = 2018-10-27 00:00:00 +0000
kMDItemContentModificationDate = 2018-10-27 06:08:22 +0000
kMDItemContentType = "net.daringfireball.markdown"
kMDItemContentTypeTree = (
"net.daringfireball.markdown",
"public.item",
"public.text",
"public.data",
"public.content",
"net.daringfireball.markdown",
"public.plain-text"
)
kMDItemDateAdded = 2018-10-27 06:08:22 +0000
kMDItemDateAdded_Ranking = 2018-10-27 00:00:00 +0000
kMDItemDisplayName = "index.md"
kMDItemFSContentChangeDate = 2018-10-27 06:08:22 +0000
kMDItemFSCreationDate = 2018-10-27 06:08:22 +0000
kMDItemFSCreatorCode = ""
kMDItemFSFinderFlags = 0
kMDItemFSHasCustomIcon = (null)
kMDItemFSInvisible = 0
kMDItemFSIsExtensionHidden = 0
kMDItemFSIsStationery = (null)
kMDItemFSLabel = 0
kMDItemFSName = "index.md"
kMDItemFSNodeCount = (null)
kMDItemFSOwnerGroupID = 20
kMDItemFSOwnerUserID = 501
kMDItemFSSize = 175
kMDItemFSTypeCode = ""
kMDItemInterestingDate_Ranking = 2018-10-27 00:00:00 +0000
kMDItemKind = "Plain Text Document"
kMDItemLogicalSize = 175
kMDItemPhysicalSize = 4096
You can find more information on metadata attributes, as well as some advanced mdfind
queries here.
Another cool thing about mdfind
is that you never have to rebuild its database
manually, as this is automatically handled by macOS. When I was using GNU/Linux
back in the day I’d have to setup some cron job to keep my locate
database up
to date, and occasionally I’d had to trigger its update manually.
That’s all I have for you today. I’d love it if you share in the comments some of your favourite uses of mdfind
. See you tomorrow!
-
I believe MD stands for “meta data”. ↩