How to Search for Files on Mac by Typing the Query

The search field on a Mac accepts far more than a fragment of a filename. Most sessions go the same way: a word gets typed, several hundred results come back, the list gets scrolled, and the file that was wanted turns out to be somewhere in the middle of it. The usual advice at that point is to click the plus button and start adding criteria rows. That works, but it is slow, it has to be redone every time, and it hides the fact that macOS already accepts a written query language in the same box. The keywords are documented, they work in Spotlight and in a Finder window, and the same expressions can be run from a shell. What follows is what that language covers, and the point where a better query stops being the answer.

Clicking criteria and typing them produce the same query

The criteria rows under a Finder search window are a builder. Each row picks an attribute, a comparison, and a value, and the window turns the whole set into a metadata query before anything is matched. Typing kind:pdf into the search field does the same thing in one step. Neither route is more powerful than the other in what it can express. They differ in how long they take and in how much of the vocabulary they reveal.

The builder is discoverable. Every attribute macOS knows about is sitting in the Other list, with a human readable name next to it, so an attribute that was never known to exist can still be found by scrolling. The cost is that a four condition search takes a dozen clicks, and none of it survives closing the window.

Typed keywords are the opposite. They take a second to enter and they can be pasted, saved in a note, or dropped into a script, but nothing on screen tells anyone that they exist. That is the reason so many searches on a Mac stay at the level of a single word: the vocabulary is real, documented, and invisible.

The practical approach is to use both. Type the part that is remembered, then open the criteria builder only for the condition that has no keyword, such as a specific colour label or a raw pixel dimension.

The keywords the search field already understands

Apple documents a set of keyword and value pairs that work in the Spotlight menu and in the Finder search field. The pattern is always the same: keyword, colon, then the value, with no space after the colon. Multi word values go in quotation marks.

Keyword What it matches Example
kind: The type of item kind:pdf
name: Words in the filename name:invoice
author: The document author stored in metadata author:tom
by: The artist or creator field by:"glenn miller"
created: The creation date created:8/16/24
modified: The modification date, with <= and >= modified:<=7/29/24
date: A date, or a range written with a hyphen date:6/29/24-7/25/24
tag: A Finder tag tag:red

Apple's own examples show how these combine. trip kind:document looks for the word trip in documents only. kind:images created:8/16/24 returns images created on one date. The keyword can sit at the start or the end of the query, so New York City kind:images and kind:images New York City do the same job.

Two behaviours are worth knowing before relying on this. The value after kind: is matched against a list of item types, not against the file extension, so kind:image and kind:images both work while kind:jpeg does not. And contains:, title:, keyword:, from:, to: and with: exist as well, which matters most when the item being hunted is a mail message or a calendar event rather than a file on disk.

Boolean operators, exclusion, and the row that stays hidden

Multiple keywords in one query are combined with AND by default. To express anything else, the operators have to be written out in capitals.

author:tom OR author:thom covers a name whose spelling is uncertain. trip -france returns items containing trip and not containing france, because a leading minus sign means AND NOT. kind:message date:6/29/24-7/25/24 NOT date:7/14/24 narrows to a date range and then carves one day back out of it.

The same logic exists in the criteria builder, but it is deliberately hidden. Holding the Option key changes the plus button at the end of a criteria row into a different control, and clicking that adds a nesting row where Any, All, or None of the conditions below it must be met. Without the Option key held, the builder can only ever produce a flat list of conditions joined by AND, which is why complicated searches assembled by clicking so often return nothing.

The most common cause of an empty result set is an unintended AND. Four criteria rows mean four conditions that must all be true at once. Adding a date range to a name search, when the date on the file is not the date the reader is thinking of, silently removes every correct result. When a search returns zero items, deleting conditions one at a time is faster than rewriting the query.

Reading the attribute names off a file already on disk

Every keyword above is a shorthand for a metadata attribute with a longer real name, and there are far more attributes than there are keywords. Selecting a file and choosing File then Get Info shows the human readable version of some of them. The complete set for one specific file comes from mdls:

mdls ~/Documents/report.pdf
mdls -name kMDItemContentType -name kMDItemKind ~/Documents/report.pdf

The output names every attribute the indexer actually stored for that file, which answers a question that guessing never will: whether the thing being searched for was ever recorded. A scanned PDF with no text layer has no kMDItemTextContent, and no query will find a word inside it. A file copied off a camera has kMDItemFSName and little else.

To see the full vocabulary rather than one file's worth of it, mdimport -X prints the attribute schema, which on current macOS runs to over a thousand lines. Reading it once is a reasonable investment, because attributes such as kMDItemPixelHeight, kMDItemDurationSeconds and kMDItemWhereFroms have no keyword shorthand and are only reachable through the Raw Query criterion in the Finder builder or through the command line.

Running the same query from the shell

mdfind queries the same index the Finder search field uses, which means anything excluded from the index is missing from both. What it adds is scope control, counting, and output that can be piped somewhere.

mdfind -onlyin ~/Projects -count 'kMDItemFSName == "*.md"c'
mdfind -onlyin ~/Documents 'kMDItemContentModificationDate >= $time.today(-7)'
mdfind -0 -onlyin ~/Downloads 'kMDItemFSName == "*.zip"c' | xargs -0 ls -lh

The c after a value makes the comparison case insensitive, and cd makes it ignore both case and diacritics. $time.today(-7) resolves to midnight seven days ago, and $time.now, $time.this_month and similar tokens exist alongside it. Conditions join with && and ||.

Four options carry most of the weight. -onlyin limits the search to one directory, which is the difference between a usable result and the whole disk. -count returns a number instead of paths, which is how a query gets tested before it is trusted. -live keeps running and updates the count as files change. -interpret parses the argument the way the Spotlight menu would, so mdfind -interpret "kind:pdf report" behaves like the menu bar rather than like a raw expression.

Route Scope control Survives closing the window Output can be piped
Spotlight menu No No No
Finder search window Yes No No
Smart Folder Yes Yes No
mdfind Yes Yes, as a shell function Yes

Saving the query so it never has to be typed twice

A search that gets rebuilt every month is a search that will eventually be rebuilt wrong. Once a query returns the right set, clicking Save under the search field stores it as a Smart Folder, and leaving Add To Sidebar selected puts it one click away in every Finder window. Option+Command+N creates an empty Smart Folder to start from.

Smart Folders hold the criteria, not the files, so the contents are recalculated every time the folder is opened. That makes them good for standing questions such as everything modified in the last week inside one project directory, and bad as a filing system, because nothing is actually stored there and moving the underlying file changes what appears.

The builder behind a Smart Folder also accepts a raw expression. In the criteria row, choosing Other and then Raw Query allows the same kMDItem syntax used by mdfind to be pasted straight in, which is the only way to reach attributes that have no friendly name in the list. A query developed and tested at the command line can therefore be moved into the Finder without being rewritten.

On the shell side, the equivalent is a function in a shell profile that wraps mdfind -onlyin with a fixed directory. The point in both cases is the same: the thinking happens once.

Where a better query stops helping

Query skill has a ceiling, and it arrives sooner than expected. Once the right twelve files are on screen, the remaining work is not searching. It is opening one to check, copying a path into a terminal to run something against the rest, moving a subset somewhere else, and then repeating the whole cycle because the next question is slightly different from the last one.

That part is not made faster by a better keyword. It is made slower by the number of windows involved, since the result list lives in one application, the shell command lives in another, and the path has to be carried between them by hand. Tools that put a directory listing and a terminal in the same window remove that carry, which is the case set out in Features and measured against other options in Compared with other file managers. The specific question of what happens to a query when the work moves to another device is covered in From iPhone and iPad.

The other hard limit is coverage. No query reaches a volume with indexing switched off, a folder listed under Spotlight privacy settings, or the inside of an unopened archive. When a well formed query returns nothing, the next check is the index, not the wording.

What to change first

Pick the one search that gets retyped most often, write it as keywords rather than clicks, and save it as a Smart Folder with Add To Sidebar left on. Then run the same expression through mdfind -count so the number can be trusted before anything is acted on. If the step after the search is always a shell command, a file manager with a terminal in the same window such as Atriens removes the part of the loop that no query can shorten.

Frequently asked questions

Why does a query with several keywords return nothing at all?

Keywords are joined with AND unless an operator says otherwise, so every condition has to be true for the same file. A date condition is the usual culprit, because created, modified, and last opened are three different dates and the one on the file is often not the one being remembered. Remove conditions one at a time until results appear, then add back only the condition that was actually needed.

Is there a way to search by file extension rather than by kind?

kind: matches item types rather than extensions, so it cannot separate two formats that macOS treats as the same kind. Matching an extension directly requires the filename attribute, either through the Name criterion set to ends with, or at the command line with an expression such as kMDItemFSName == "*.psd"c. The same expression can be pasted into a Raw Query criterion inside a Smart Folder.

Do typed keywords work in the Save and Open dialogs?

The search field in a save or open dialog uses the same index and accepts the same keyword syntax, so kind:folder and modified: behave as they do in a Finder window. What is missing is the criteria builder and the Save button, so a query used in a dialog cannot be turned into a Smart Folder from there. Build it in a Finder window first, then reach it from the dialog sidebar.

Why do results differ between mdfind and the Finder search window?

Both read the same metadata store, so the difference is almost always scope rather than content. A Finder window may be searching only the current folder depending on the Advanced setting in Finder settings, while mdfind without -onlyin searches everything the index covers. Running mdfind -onlyin against the same directory usually makes the two agree.

Can a query find text inside a file rather than in its name?

Indexed formats have their text stored in the kMDItemTextContent attribute, so a bare word in the search field already matches file contents for those formats. Files with no text layer, such as scanned PDFs without recognised text, have no value in that attribute and cannot be matched no matter how the query is written. Running mdls on one example file shows immediately which case applies.

Back to all posts