Mac search for file extension, done accurately
Typing .psd into a Finder window returns files with psd in the name, files that mention psd somewhere in their text, and a scattering of results that appear to have nothing to do with either. Choosing Kind and then Image narrows it, but the list still holds PNGs and JPEGs. The reason is that Finder search is built around what a file is, and an extension is a statement about what a file claims to be. Those two things usually agree and occasionally do not, and every frustrating search on macOS lives in the gap between them. There is a Finder criterion that filters on the extension itself, there are two command line tools that do it more precisely, and there is a setting that silently changes what any of them cover.
Kind and extension answer different questions
When macOS indexes a file it assigns it a type identifier, a reverse domain string such as com.adobe.photoshop-image or net.daringfireball.markdown. The Kind row in Finder search filters on that identifier. The extension is a few characters at the end of the filename, and while the identifier is usually derived from it, the mapping is not fixed and it is not universal.
Two consequences follow. The first is that Kind is broader than an extension by design. Kind is Image covers every format the system recognises as an image, so a search for Photoshop files will not be isolated by it. The second is more awkward: which identifier an extension resolves to depends on what applications are installed on that particular Mac, because applications declare the types they handle. A file with the same extension can report one identifier on a work machine and a different one on a laptop, which is why a saved search that behaved perfectly on one Mac returns a different set on another.
To see what a specific file is registered as, run mdls -name kMDItemContentType followed by the path. The value that comes back is exactly what the Kind row is matching against. This is worth doing once on a file you care about, because it usually explains a search that returned too much or too little.
The practical rule is simple. When the question is "every image in this folder", Kind is the right instrument. When the question is "every .psd, and nothing else", Kind is the wrong instrument and the extension has to be matched directly.
The Finder criterion most people never open
Finder search has a row for exactly this, and it is not visible until it is added. Open the folder, press Command-F, then click the plus button on the right below the search field. A criterion row appears, defaulting to Kind. Click the leftmost pop-up menu in that row and choose Other.
A long list of attributes opens with a search field at the top. Typing extension brings up File extension, which produces a row reading File extension is, with a text box for the value. Enter psd without the leading dot. Combined with a location of the current folder rather than This Mac, this returns files whose name actually ends in that extension and nothing else.
Two other entries in that same list are worth knowing. Raw Query accepts a metadata query written out in full, which is the escape hatch when the pre-built rows cannot express the question. System files gives a row reading System files are included or aren't included, which matters when the target sits inside a bundle or a Library folder that Finder normally keeps out of results.
There is a shorter route that covers most cases without opening the Other list. Choose Name in the first pop-up, then ends with in the second, then type .psd with the dot. It is less precise than the extension row, because a folder named archive.psd would also match, but it takes three clicks. Apple's guidance on building these rows is direct about the effect of stacking them:
To appear in the search results, an item must match all your criteria. For example, if one criterion specifies searching for items whose name begins with S and you add a criterion to search for items created today, the search results include only items created today whose names begin with S. Source: support.apple.com
Matching more than one extension
A single row handles one extension. Asking for raw camera files that might be .cr2, .nef, or .arw needs three rows joined by an Any condition rather than the default All, because no file can end in three extensions at once. Hold Option and click the plus button, choose Any of the following are true, then add one File extension row per format inside that group. The group can be nested under an outer All condition that also constrains the date or the size, which is how a request such as "raw files from this shoot, larger than 20 MB" gets expressed without leaving the window.
The order of the rows makes no difference to the result and a large difference to how readable the search is a month later. Putting the location and the date at the top and the format rows in a group at the bottom keeps a saved search legible when it needs editing.
Holding the Option key while clicking the plus button turns it into a different symbol that adds a group, which is how Any, All, and None conditions get built. That is the route to "either .psd or .ai" in a single search.
The setting that changes what any search covers
There is a Finder setting that decides where a search starts, and it accounts for a large share of searches that appear to be broken. Choose Finder, then Settings, then Advanced, and look at When performing a search. The three options are searching the entire Mac, searching the folder that is currently open, or repeating whatever scope was used last time.
The default sends every new search to This Mac. Someone who opens a project folder, presses Command-F and types an extension is then looking at results from the whole disk, with the project folder's own files buried among caches and downloads. The bar above the results has This Mac and the folder name as buttons, so a single click fixes it for that search, but the setting fixes it permanently.
Scope has a second dimension that is easy to miss. Spotlight based search only returns what has been indexed. System Settings, then Spotlight, then Search Privacy holds a list of locations excluded from indexing, and anything inside them is invisible to Finder search regardless of how the criteria are set. External drives, network volumes, and disk images may also carry no index at all. A search that returns nothing on an external drive is usually reporting an absent index, not an absent file.
Turning a search into something reusable
A search built from criteria rows can be saved. Click Save below the search field and it becomes a Smart Folder, a saved query that re-runs every time it is opened. Leaving Add To Sidebar selected puts it in the Finder sidebar, where it behaves like a folder that always contains the current answer. Option-Command-N creates one from scratch.
This is the right shape for a question that gets asked repeatedly. A Smart Folder set to File extension is sketch inside a client folder is a permanent, self-updating list of every Sketch file in that project. Editing it later means opening it and clicking the action button, then Show Search Criteria.
The limitation is that a Smart Folder is a view, not a container. The files stay where they are. Dragging one out of a Smart Folder moves the original, which is occasionally surprising the first time. Deleting the Smart Folder deletes only the saved query.
The same question at the command line
Two tools answer this, and they work on different principles.
mdfind queries the same index Finder uses, so it is fast and it inherits the same blind spots. The precise form matches the filename attribute against a pattern:
mdfind -onlyin ~/Projects "kMDItemFSName == '*.psd'"
The comparison is case sensitive by default, so a file saved as Cover.PSD is missed. Appending a c after the closing quote makes it case insensitive:
mdfind -onlyin ~/Projects "kMDItemFSName == '*.psd'c"
The convenience flag -name is tempting and it is not equivalent. It matches the string anywhere in the filename, so mdfind -name md returns files ending in .md and also files named notes.mdx, along with anything containing those two letters in the middle of a word. For extension work the explicit attribute comparison is the one to use.
find does not touch the index at all. It walks the directory tree and compares names as it goes:
find ~/Projects -type f -name "*.psd"
It is slower on large trees and it works in places mdfind cannot reach, including excluded folders, freshly mounted volumes, and drives with no index. -iname makes it case insensitive. Because the output is one path per line, it feeds directly into anything else, which is the real reason to reach for it.
Speed is the trade-off that decides between them in practice. On a home folder with a few hundred thousand files, mdfind answers in well under a second because it is reading a database that was built in advance. find on the same tree takes noticeably longer because it is opening every directory in turn, and the gap widens on spinning disks and network shares. The reverse holds on a volume that was plugged in a minute ago: mdfind returns nothing at all until indexing finishes, while find starts producing paths immediately.
There is also a difference in what counts as a match. find sees the filesystem, so it reports files inside application bundles, inside node_modules, and inside hidden directories without being asked. mdfind follows the same exclusions Finder does. Neither behaviour is correct in general, and knowing which one is in play prevents a lot of second-guessing when the two tools disagree about a count.
| Route | Matches the extension exactly | Case insensitive | Needs an index | Output usable elsewhere |
|---|---|---|---|---|
| Finder, File extension row | Yes | Yes | Yes | No, results are a window |
| Finder, Name ends with | Close, folders match too | Yes | Yes | No |
mdfind with kMDItemFSName |
Yes | With the c suffix |
Yes | Yes, one path per line |
mdfind -name |
No, substring anywhere | Yes | Yes | Yes |
find -name |
Yes | With -iname |
No | Yes |
When the extension is not on screen
A search by extension assumes the extension is visible, and by default many are not. Each file carries a Hide extension flag, set in the Get Info window, and Finder honours it per file. The system wide override sits in Finder settings:
Show all file extensions, even for files that have "Hide extension" selected. Source: support.apple.com
Turning Show all filename extensions on in the Advanced pane is worth doing before any of this, because it makes the thing being searched for visible. The flag only affects display. A file shown as report is still report.pdf on disk, and both the File extension row and mdfind find it either way. What changes is whether the extension can be read off the screen when checking whether the results are correct.
The other display detail that misleads is localisation. Folder names such as Documents and Downloads are shown translated on a system set to another language while the directory on disk keeps its English name. Anything typed into find or mdfind -onlyin has to use the name on disk, not the one in the window.
What to change first
Open Finder settings, set When performing a search to the current folder, and turn on Show all filename extensions. Those two changes remove most of the confusion before any search is typed. Then build the File extension row once, save it as a Smart Folder for the extension asked about most often, and keep mdfind -onlyin for the times the answer needs to become the input to something else. Where the search results and a shell are needed in the same place rather than in two applications, Atriens is built around that arrangement, and the trade-offs against the alternatives are set out in Compared with other file managers.
Frequently asked questions
How do you search by file extension in Finder?
Press Command-F, click the plus button below the search field, then set the first pop-up to Other and pick File extension from the list. The row becomes File extension is, and the value goes in without a leading dot. Set the location bar to the current folder rather than This Mac, otherwise the results cover the whole disk.
Why does searching for pdf return files that are not PDFs?
The plain search field looks at names, text content, and metadata together, so a document that mentions the word is a valid hit. Choosing Kind narrows it to the type identifier the system assigned, which is close to but not the same as the extension. Only the File extension criterion, or a kMDItemFSName comparison in mdfind, filters on the characters at the end of the filename.
What is the Terminal command to find all files with a given extension?
mdfind -onlyin ~/Projects "kMDItemFSName == '*.psd'" uses the Spotlight index and is fast. Add a c after the closing quote to ignore case. find ~/Projects -type f -name "*.psd" reads the directories directly and works on drives with no index, including external volumes and folders excluded from Spotlight.
Why does a search on an external drive return nothing?
Spotlight based search only returns indexed items, and external drives, disk images, and network volumes are often not indexed. Locations listed under System Settings, Spotlight, Search Privacy are excluded as well. Running find on the mounted volume bypasses the index entirely and will show the files if they are there.