19 Feb 2025
Ways to Find Files in macOS Terminal
To find files in macOS Terminal, you can use several main commands:
find- This command is used to search for files and directories in a directory hierarchy based on a specified expression.- Example:
find /path/to/directory -name "filename"
Use find to search for files or directories by name, type, size, etc.
locate- Utilizes a pre-built database to quickly find files. The database needs to be updated periodically usingsudo /usr/libexec/locate.updatedb.-
Example:
locate filename -
mdfind- This command uses macOS's Spotlight indexing to search for files = fastest. -
Example:
mdfind "search term" -
grep- While primarily used to search within files, it can be combined with other commands to search for files containing specific text. - Example:
grep -r "search text" /path/to/directory
grep stands for Global Regular Expression Print.
It is a command-line tool used in Unix-based systems (including macOS) to search for specific text patterns within files.
It searches for lines matching a pattern in files.
Use grep to search inside files for text.
ls- Basic command to list files in directories, can be combined with other commands or options to refine search.- Example:
ls -R | grep "filename"
Each of these commands can be modified with various options to refine searches, such as filtering by file type or modifying search depth.
| Goal | Best Tool | Why |
|---|---|---|
| By file content | grep |
Searches inside files for matching text |
| By file name (fast) | mdfind |
Uses macOS Spotlight index = very fast |
| By file name (portable) | find |
Works on all Unix systems, doesn't rely on index |
| By file name (if indexed) | locate |
Super fast, but needs sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist to enable DB |
| Just listing files | ls |
Only shows what's in the directory, no search at all |
Commands
find
- Basic Syntax:
-
find [path] [expression]- Searches for files and directories starting from the specified[path]and matches them against the given[expression]. -
Common Flags:
-name [name]: Searches for files by name.- Example:
find / -name "example.txt"
- Example:
-type [type]: Searches for a type of file.[type]can beffor files ordfor directories.- Example:
find /path/to/directory -type f
- Example:
-mtime [n]: Finds files modifiedndays ago.- Example:
find . -mtime -7(modified in the last 7 days)
- Example:
-size [n]: Finds files of a specific size.[n]can be in kilobytes (k), megabytes (M), etc.- Example:
find / -size +10M
- Example:
-
-exec [command] {} \;: Executes a command on each matching file.- Example:
find . -name "*.txt" -exec grep "searchtext" {} \;
- Example:
-
Logical Operators:
-and: Combines expressions (can be omitted, as it's the default).-or: If either expression is true, the file is a match.-
!: Negates an expression. -
Examples:
- Search for files owned by a specific user:
find / -user [username] - Find empty files:
find /path/to/directory -type f -empty - List files created within the last 24 hours:
find / -ctime -1
locate
The locate command in macOS is used to quickly find files by searching through a pre-built database. Here are the basic aspects and options associated with the command:
- Basic Usage:
-
locate [filename]: Searches for files matching the given[filename]within the system database. -
Update the Database:
-
sudo /usr/libexec/locate.updatedb: Updates the database used by thelocatecommand. This command may require superuser privileges. -
Options:
-i: Ignore case distinctions in patterns and data.- Example:
locate -i "example.txt"
- Example:
-d [path-to-database]: Specifies an alternative database forlocateto use.- Example:
locate -d /my/other/database "search_term"
- Example:
-r [expression]: Interprets the search term as a regular expression.- Example:
locate -r 'my.*file'
- Example:
The locate command is generally faster than find because it relies on an indexed database of system paths, which must be updated manually or may be scheduled to update periodically. This speed comes at the cost of potentially having less up-to-date results compared to real-time search methods.
mdfind
The mdfind command in macOS uses the Spotlight index to search for files. Here are the essential options and usage examples:
- Basic Usage:
-
mdfind "search text": Searches for files that match the specified query using Spotlight's index. -
Search by File Type:
-
mdfind "kMDItemContentType == 'public.text'": This example searches for all text files. You can replace'public.text'with the relevant content type for other file types. -
Search in Specified Directory:
-
mdfind -onlyin /path/to/directory "search text": Limits the search to a specific directory. -
Refining the Search:
-
mdfind "kind:image" && mdfind "date:today": You can use Spotlight attributes likekind,date, etc., for more refined searches. -
Search by Metadata:
-
mdfind -name "example.txt": Searches specifically by file name. -
Exclude System Files:
mdfind -0 "search text": Searches without descending into system files, useful for excluding hidden or system-specific files.
The mdfind command is very powerful when you need to perform quick searches across the entire system based on indexed metadata. It benefits users looking for a more efficient search than some of the more extensive real-time searches like find.
grep
The grep command is used for searching text within files in macOS Terminal. Here are the basic options and usage examples:
- Basic Usage:
grep "pattern" [file]: Searches for the specified "pattern" within the provided [file].-
Example:
grep "error" logfile.txt -
Recursive Search:
grep -r "pattern" [directory]: Searches recursively through all files in the specified directory.-
Example:
grep -r "TODO" ./project -
Ignore Case Sensitivity:
grep -i "pattern" [file]: Ignores case distinctions when searching.-
Example:
grep -i "warning" logfile.txt -
Display Line Numbers:
grep -n "pattern" [file]: Displays the line number along with each match.-
Example:
grep -n "error" logfile.txt -
Count Matches:
grep -c "pattern" [file]: Counts the number of lines that match the pattern.-
Example:
grep -c "error" logfile.txt -
Show only Matching Part:
grep -o "pattern" [file]: Prints only the matching part from each line.- Example:
grep -o "http://[a-zA-Z0-9./]*" logfile.txt
These options make grep a versatile tool for processing and extracting information from text files in a variety of contexts.
ls
The ls command in macOS Terminal is used to list directory contents. Here are the basic options and commands:
- Basic Listing:
-
ls: Lists files and directories in the current working directory. -
List with Details:
-
ls -l: Provides a detailed listing, showing file permissions, number of links, owner, group, size, and modification date. -
Include Hidden Files:
-
ls -a: Shows all files, including hidden ones (those starting with a dot.). -
List with Human-Readable Sizes:
-
ls -lh: Displays sizes in a more readable format such as KB, MB, rather than bytes. -
Sort by Modification Time:
-
ls -lt: Sorts files by modification time, most recently modified first. -
Recursive Listing:
-
ls -R: Lists all files and directories with their subdirectories recursively. -
Combining Options:
- You can combine multiple options. For example,
ls -lawill show detailed information including hidden files.
These options allow you to customize the display of directory and file listings according to your needs.
Faster tools
20 Sep 2026 the commands above work on any Unix box and are worth keeping for that reason. Everything below is faster, and most of it is already installed here.
Already on this Mac: fd, rg, fzf, zoxide, yazi, plus the built-in mdfind. That set (fd, ripgrep, fzf, zoxide, yazi) is also what the terminal crowd on X has converged on.
| Tool | Replaces | What it does |
|---|---|---|
fd |
find |
Filename search, skips hidden and ignored files by default |
rg |
grep -r |
Content search, parallel, .gitignore aware |
fzf |
nothing | Fuzzy filter for any list, pipes into anything |
zoxide |
cd |
Jumps to directories by how often you use them |
yazi |
browsing by ls |
File manager with previews, calls fd and rg inside |
mdfind |
find on macOS |
Spotlight index, whole disk, instant |
Measured here
Same machine, same corpus, real numbers:
| Search | Corpus | Command | Time |
|---|---|---|---|
| Content | 98,796 files in ~/sites |
grep -ril |
32.08s |
| Content | Same | rg -li |
6.64s |
| Content | Whole home directory | mdfind -onlyin ~ |
0.15s |
| Filename | 149,863 files in ~/ai |
fd |
0.42s |
| Filename | Same | fd -HI |
1.34s |
| Filename | Whole home directory | mdfind -onlyin ~ -name |
0.72s |
Two things fall out of that. The index wins whenever it is warm: Spotlight searched the whole home directory for text in 0.15s while grep spent 32s on a fraction of it. And fd is fast largely because of what it skips. The same search with -HI, which turns off the ignore rules and includes hidden files, costs 3 times as much.
Recipes
# filename, current directory down
fd invoice
# include hidden files and ignored paths
fd -HI invoice
# by extension, then run something on each hit
fd -e md -x wc -l
# content, case-insensitive
rg -i kaltura
# just the file names, not the matching lines
rg -l kaltura
# restrict to a language
rg -t py argparse
# pick a file interactively, then open it
fd -t f | fzf | xargs open
# Spotlight: content, anywhere, instant
mdfind -onlyin ~ "gap selling"
# Spotlight: files over 1GB
mdfind 'kMDItemFSSize > 1073741824' -onlyin ~
# Spotlight: filename only
mdfind -onlyin ~ -name 260909-digitalx
⚠️ WARNING:
mdfindonly knows what Spotlight indexed. External drives, network shares and privacy-excluded folders return nothing, which looks exactly like "no match". Check the volume first withmdutil -s /Volumes/NAME, and fall back tofdorrgwhen it is not indexed.
Worth knowing, not installed
| Tool | Why look |
|---|---|
| tgrep | Trigram-indexed grep from Microsoft, aimed at repos too big for rg |
| television | Fuzzy finder with ready-made channels: files, text, git, env |
| broot | Tree navigator that folds a huge directory onto one screen |
| ugrep | grep-compatible flags, searches inside archives and PDFs |
| skim | fzf, rewritten in Rust |
| fselect | SQL over the filesystem: select name from . where size gt 10mb |
| ast-grep | Searches code by syntax tree instead of text |
The indexed tools are the interesting direction. tgrep claims large multiples over ripgrep on big trees, though I have not tested that here. On a Mac the index already exists and is free, so mdfind covers most of that ground.
Which one
- Inside a project:
rgfor text,fdfor names. They respect.gitignore, so results stay clean. - Anywhere on the Mac:
mdfind. Nothing beats a warm index. - Don't know the name:
fd -t f | fzf, or openyaziand browse with previews. - On a server over SSH:
findandgrep. They are always there, which is the whole point of keeping the first half of this note.