Finding files using macOS Terminal

19 Feb 2025

Ways to Find Files in macOS Terminal

To find files in macOS Terminal, you can use several main commands:

  1. find - This command is used to search for files and directories in a directory hierarchy based on a specified expression.
  2. Example: find /path/to/directory -name "filename"

Use find to search for files or directories by name, type, size, etc.

  1. locate - Utilizes a pre-built database to quickly find files. The database needs to be updated periodically using sudo /usr/libexec/locate.updatedb.
  2. Example: locate filename

  3. mdfind - This command uses macOS's Spotlight indexing to search for files = fastest.

  4. Example: mdfind "search term"

  5. grep - While primarily used to search within files, it can be combined with other commands to search for files containing specific text.

  6. 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.

  1. ls - Basic command to list files in directories, can be combined with other commands or options to refine search.
  2. 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

  1. Basic Syntax:
  2. find [path] [expression] - Searches for files and directories starting from the specified [path] and matches them against the given [expression].

  3. Common Flags:

  4. -name [name]: Searches for files by name.
    • Example: find / -name "example.txt"
  5. -type [type]: Searches for a type of file. [type] can be f for files or d for directories.
    • Example: find /path/to/directory -type f
  6. -mtime [n]: Finds files modified n days ago.
    • Example: find . -mtime -7 (modified in the last 7 days)
  7. -size [n]: Finds files of a specific size. [n] can be in kilobytes (k), megabytes (M), etc.
    • Example: find / -size +10M
  8. -exec [command] {} \;: Executes a command on each matching file.

    • Example: find . -name "*.txt" -exec grep "searchtext" {} \;
  9. Logical Operators:

  10. -and: Combines expressions (can be omitted, as it's the default).
  11. -or: If either expression is true, the file is a match.
  12. !: Negates an expression.

  13. Examples:

  14. Search for files owned by a specific user: find / -user [username]
  15. Find empty files: find /path/to/directory -type f -empty
  16. 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:

  1. Basic Usage:
  2. locate [filename]: Searches for files matching the given [filename] within the system database.

  3. Update the Database:

  4. sudo /usr/libexec/locate.updatedb: Updates the database used by the locate command. This command may require superuser privileges.

  5. Options:

  6. -i: Ignore case distinctions in patterns and data.
    • Example: locate -i "example.txt"
  7. -d [path-to-database]: Specifies an alternative database for locate to use.
    • Example: locate -d /my/other/database "search_term"
  8. -r [expression]: Interprets the search term as a regular expression.
    • Example: locate -r 'my.*file'

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:

  1. Basic Usage:
  2. mdfind "search text": Searches for files that match the specified query using Spotlight's index.

  3. Search by File Type:

  4. 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.

  5. Search in Specified Directory:

  6. mdfind -onlyin /path/to/directory "search text": Limits the search to a specific directory.

  7. Refining the Search:

  8. mdfind "kind:image" && mdfind "date:today": You can use Spotlight attributes like kind, date, etc., for more refined searches.

  9. Search by Metadata:

  10. mdfind -name "example.txt": Searches specifically by file name.

  11. Exclude System Files:

  12. 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:

  1. Basic Usage:
  2. grep "pattern" [file]: Searches for the specified "pattern" within the provided [file].
  3. Example: grep "error" logfile.txt

  4. Recursive Search:

  5. grep -r "pattern" [directory]: Searches recursively through all files in the specified directory.
  6. Example: grep -r "TODO" ./project

  7. Ignore Case Sensitivity:

  8. grep -i "pattern" [file]: Ignores case distinctions when searching.
  9. Example: grep -i "warning" logfile.txt

  10. Display Line Numbers:

  11. grep -n "pattern" [file]: Displays the line number along with each match.
  12. Example: grep -n "error" logfile.txt

  13. Count Matches:

  14. grep -c "pattern" [file]: Counts the number of lines that match the pattern.
  15. Example: grep -c "error" logfile.txt

  16. Show only Matching Part:

  17. grep -o "pattern" [file]: Prints only the matching part from each line.
  18. 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:

  1. Basic Listing:
  2. ls: Lists files and directories in the current working directory.

  3. List with Details:

  4. ls -l: Provides a detailed listing, showing file permissions, number of links, owner, group, size, and modification date.

  5. Include Hidden Files:

  6. ls -a: Shows all files, including hidden ones (those starting with a dot .).

  7. List with Human-Readable Sizes:

  8. ls -lh: Displays sizes in a more readable format such as KB, MB, rather than bytes.

  9. Sort by Modification Time:

  10. ls -lt: Sorts files by modification time, most recently modified first.

  11. Recursive Listing:

  12. ls -R: Lists all files and directories with their subdirectories recursively.

  13. Combining Options:

  14. You can combine multiple options. For example, ls -la will 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: mdfind only knows what Spotlight indexed. External drives, network shares and privacy-excluded folders return nothing, which looks exactly like "no match". Check the volume first with mdutil -s /Volumes/NAME, and fall back to fd or rg when 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: rg for text, fd for 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 open yazi and browse with previews.
  • On a server over SSH: find and grep. They are always there, which is the whole point of keeping the first half of this note.