Sweepfor Mac

Mac maintenance

How to Use mdfind: Spotlight From the Terminal

Use mdfind on macOS for fast Spotlight searches from the Terminal — with practical query syntax, metadata attributes, and real-world examples.

9 min read

You’re trying to find every PDF you downloaded last March, or every file an uninstalled app left behind, or every photo with GPS coordinates in San Francisco. Finder’s search box can do some of this, but the syntax is hidden, the speed is uneven, and you can’t pipe results into another command.

mdfind is Spotlight from the Terminal. Same index, much more flexibility, instant pipe-friendly output. Here’s how to use it.

The basics

mdfind "swift"

Returns every file Spotlight has indexed that matches swift — by name or content. Hundreds of results probably. To narrow:

mdfind -onlyin ~/Documents "swift"

Limits the search to a specific directory tree. You can pass -onlyin multiple times to search several roots.

To search filenames only:

mdfind -name "invoice"

Note that -name does a substring match on the filename. So mdfind -name "2026" finds anything with 2026 in its name.

To get only the count:

mdfind -count "swift"

To watch for new matches in real time (a “live query”):

mdfind -live "kind:image"

It prints results as files are added or modified. Ctrl+C to stop.

Tip: If `mdfind` returns nothing for something you can clearly see in Finder, the location may be excluded from Spotlight. Check with mdutil -s / or System Settings → Spotlight → Privacy.

The query syntax (the part Spotlight UI hides)

Spotlight queries are key/value expressions on metadata attributes. Examples:

mdfind 'kMDItemContentType == "com.adobe.pdf"'
mdfind 'kMDItemFSSize > 100000000'
mdfind 'kMDItemKind == "JPEG image"'
mdfind 'kMDItemFSCreationDate >= $time.iso(2026-03-01)'

== is exact match, = (single equals) is the loose match Spotlight uses by default. Wrap strings in double quotes inside the single-quoted query. The $time.iso(...) form is how you express dates.

Logical operators:

mdfind 'kMDItemContentType == "com.adobe.pdf" && kMDItemFSSize > 5000000'
mdfind 'kMDItemDisplayName == "*.psd"c'

The trailing c makes the comparison case-insensitive. w makes it word-based (matches swift in Swift Programming.pdf but not swiftly).

Common attributes you’ll actually use

mdfind’s power comes from knowing the attribute names. The big ones:

  • kMDItemDisplayName — the file name shown to the user
  • kMDItemContentType — UTI like public.image, com.adobe.pdf, public.python-script
  • kMDItemContentTypeTree — array of parent UTIs, useful for “any image”
  • kMDItemFSSize — file size in bytes
  • kMDItemFSCreationDate / kMDItemContentCreationDate
  • kMDItemFSContentChangeDate / kMDItemContentModificationDate
  • kMDItemKind — the human-readable type (“JPEG image”, “Folder”)
  • kMDItemAuthors, kMDItemTitle, kMDItemDescription — common doc metadata
  • kMDItemPixelWidth, kMDItemPixelHeight — image dimensions
  • kMDItemNumberOfPages — for PDFs
  • kMDItemDurationSeconds — for audio/video
  • kMDItemLatitude, kMDItemLongitude — for geotagged photos
  • kMDItemDevices, kMDItemAcquisitionMake, kMDItemAcquisitionModel — camera info
  • kMDItemDownloadedDate — when a file was downloaded (Safari sets this)
  • kMDItemUserTags — Finder tags
  • kMDItemAppStoreCategory — for .app bundles

The full list is huge. The way to discover them is mdls on a known file:

mdls ~/Documents/something.pdf

That dumps every attribute Spotlight has indexed for that file, with values. Pick the one you want and use it in mdfind.

Useful queries

Find all images larger than 5 MB:

mdfind 'kMDItemContentTypeTree == "public.image" && kMDItemFSSize > 5000000'

kMDItemContentTypeTree is the trick — public.image matches JPEG, PNG, HEIC, and so on, because they all inherit from it.

Find PDFs over 100 pages:

mdfind 'kMDItemContentType == "com.adobe.pdf" && kMDItemNumberOfPages > 100'

Find videos longer than 10 minutes:

mdfind 'kMDItemContentTypeTree == "public.movie" && kMDItemDurationSeconds > 600'

Power users use Sweep tooEven when you know the Terminal commands, Sweep is faster and harder to mess up. Get Sweep free →

Files modified in the last 24 hours:

mdfind 'kMDItemFSContentChangeDate >= $time.today(-1)'

$time.today(-1) is “one day before today.” There’s also $time.now(-3600) for relative seconds, $time.this_week, $time.this_month, $time.this_year.

Files downloaded in the last week:

mdfind 'kMDItemDownloadedDate >= $time.today(-7)'

Photos taken on a specific iPhone model:

mdfind 'kMDItemAcquisitionModel == "iPhone 15 Pro"'

Files with a specific Finder tag:

mdfind 'kMDItemUserTags == "Important"'

Files larger than 1 GB anywhere on your boot drive:

mdfind -onlyin / 'kMDItemFSSize > 1000000000'

That’s the disk-space-recovery special. Sort the results:

mdfind -0 -onlyin / 'kMDItemFSSize > 1000000000' | xargs -0 du -h | sort -h

The -0 flag uses null separators so filenames with spaces don’t break the pipeline.

Bounded ranges

Files between 10 MB and 100 MB:

mdfind 'kMDItemFSSize >= 10000000 && kMDItemFSSize <= 100000000'

Photos taken in 2025:

mdfind 'kMDItemContentCreationDate >= $time.iso(2025-01-01) && kMDItemContentCreationDate < $time.iso(2026-01-01)'

Negation

mdfind 'kMDItemContentTypeTree == "public.image" && !kMDItemContentType == "public.heic"'

Every image that isn’t HEIC. Useful when you want to find old photos to convert.

Searching only by name (when content scanning is slow)

mdfind -name "report"

This is equivalent to:

mdfind 'kMDItemDisplayName == "*report*"c'

The * wildcards and the c for case-insensitive are the boilerplate -name saves you.

Combine with shell tools

mdfind plays well with the rest of the Unix toolkit. To delete every PDF over 50 MB in your Downloads folder:

mdfind -0 -onlyin ~/Downloads 'kMDItemContentType == "com.adobe.pdf" && kMDItemFSSize > 50000000' | xargs -0 ls -lh

I’d run ls -lh first (as above), eyeball the list, then change ls -lh to rm -i once I’m sure.

To open every result in Preview:

mdfind -onlyin ~/Documents 'kMDItemContentType == "com.adobe.pdf"' | head -10 | xargs open -a Preview

To copy results to a directory:

mkdir ~/Desktop/big-images
mdfind -0 -onlyin ~ 'kMDItemContentTypeTree == "public.image" && kMDItemFSSize > 10000000' | \
  xargs -0 -I{} cp "{}" ~/Desktop/big-images/

Skip the Terminal stackSweep does the same cleanup with a UI and a preview before anything is removed. Download Sweep free →

Saved searches in Finder

Spotlight queries are what Finder’s “Smart Folders” use under the hood. To turn a query you’ve perfected in mdfind into a Smart Folder, build the same query in Finder’s search bar (use the + button to add criteria) and save the search. The criteria you can express in mdfind should all be expressible in Finder’s UI, just slower.

The reverse — taking a Smart Folder and pulling its query out — is also possible. Smart Folders are saved as .savedSearch files (XML plists) and the RawQuery key inside is exactly what mdfind accepts.

plutil -extract RawQuery xml1 -o - ~/path/to/Smart.savedSearch

When mdfind returns nothing (and Spotlight is broken)

Three common causes:

  1. The path is excluded. Check System Settings → Spotlight → Privacy. Anything in here is invisible to mdfind.
  2. The volume isn’t indexed. External drives sometimes lose their index. mdutil -s /Volumes/Drive shows status; sudo mdutil -i on /Volumes/Drive turns indexing back on.
  3. The index is stale. This shouldn’t happen but does, especially after restoring from backup. Force a reindex:
sudo mdutil -E /

That erases the Spotlight index for the whole boot volume. macOS rebuilds it in the background — expect 30 minutes to a few hours of fan noise depending on how much you’ve got.

mdls shows every Spotlight attribute for a single file:

mdls ~/Pictures/photo.heic

Useful when designing a query — you find a file you know matches, run mdls, and see exactly which attributes have values.

To extract a specific attribute:

mdls -name kMDItemPixelWidth -name kMDItemPixelHeight ~/Pictures/photo.heic

Returns just the dimensions.

Apple Silicon vs Intel

mdfind itself is unchanged across architectures. The Spotlight index format is the same. The only practical difference: Apple Silicon Macs index much faster after a fresh install or mdutil -E, because the Neural Engine handles the OCR and image-classification passes way more efficiently. On a 2017 Intel Mac, a full reindex of an SSD with hundreds of thousands of photos can take an entire day.

A few queries worth saving as scripts

~/bin/big-files:

#!/bin/bash
# Top 30 files over 100 MB in $HOME, with sizes
mdfind -0 -onlyin "$HOME" 'kMDItemFSSize > 100000000' | \
  xargs -0 du -h 2>/dev/null | sort -h | tail -30

~/bin/old-downloads:

#!/bin/bash
# Files in Downloads older than 6 months
mdfind -onlyin ~/Downloads \
  'kMDItemDownloadedDate < $time.today(-180)'

~/bin/recent-pdfs:

#!/bin/bash
mdfind -onlyin ~ \
  'kMDItemContentType == "com.adobe.pdf" && kMDItemFSCreationDate >= $time.today(-30)'

There’s a GUI for thatSweep wraps the Terminal cleanup in a UI you don’t have to memorize. Try Sweep free →

mdfind is one of those CLIs that’s hard to use until you know two or three patterns, and after that you wonder why you ever opened Finder’s search to do anything beyond the most basic file lookup. The combination of the Spotlight index (which is already there, already updating, and very fast) with the Unix pipe (which lets you do anything with the results) is hard to beat for most “find me files matching X” tasks.

← Back to all guides