find searches for files based on criteria: name, type, size, modification date, and more. It's more powerful than Spotlight for precise file finding.

Basic Usage

find /path -name "filename"

Find by Name

find . -name "file.txt"

The . means current directory. Searches recursively.

Case Insensitive (-iname)

find . -iname "readme.md"

Matches README.md, Readme.MD, readme.md, etc.

Find by Extension

find . -name "*.txt"
find . -name "*.js"
find ~/Documents -name "*.pdf"

Find by Type

Flag Type
-type f Files only
-type d Directories only
-type l Symbolic links
find . -type f -name "*.txt"    # Only files
find . -type d -name "test*"     # Only directories

Find by Size

find . -size +100M    # Larger than 100MB
find . -size -10k     # Smaller than 10KB
find . -size 50M      # Exactly 50MB

Size units: c (bytes), k (KB), M (MB), G (GB)

Find by Time

Flag Meaning
-mtime -7 Modified in last 7 days
-mtime +30 Modified more than 30 days ago
-atime Access time
-ctime Creation time
find . -mtime -1      # Modified in last 24 hours
find . -mtime +30     # Modified more than 30 days ago
find ~/Downloads -mtime +7 -name "*.dmg"

Find Empty Files/Folders

find . -type f -empty    # Empty files
find . -type d -empty    # Empty directories

Combine Conditions

AND (implicit):

find . -name "*.txt" -size +1M

Files that are .txt AND larger than 1MB.

OR (-o):

find . -name "*.jpg" -o -name "*.png"

Files that are .jpg OR .png.

NOT (!):

find . -type f ! -name "*.txt"

Files that are NOT .txt.

Limit Depth

find . -maxdepth 1 -name "*.txt"    # Current directory only
find . -maxdepth 2 -name "*.txt"    # Current + one level down

Execute Commands on Results

Delete found files:

find . -name "*.tmp" -delete

Run command on each file:

find . -name "*.txt" -exec cat {} \;

The {} is replaced with each filename. The \; ends the command.

More efficient for multiple files:

find . -name "*.txt" -exec grep "pattern" {} +

The + passes multiple files at once.

Practical Examples

Find large files:

find ~ -type f -size +500M 2>/dev/null

Clean old downloads:

find ~/Downloads -mtime +30 -type f -delete

Find recent modifications:

find . -mtime -1 -type f

Find all JavaScript files:

find . -name "*.js" -not -path "./node_modules/*"

Find and list with details:

find . -name "*.pdf" -exec ls -lh {} \;

Find duplicate filenames:

find . -type f -name "*.jpg" | xargs -n1 basename | sort | uniq -d

Count files by extension:

find . -type f -name "*.txt" | wc -l

Exclude Directories

find . -name "*.js" -not -path "*/node_modules/*"
find . -name "*.py" -not -path "*/.venv/*"

Or prune directories (faster):

find . -path ./node_modules -prune -o -name "*.js" -print

Permissions Issues

You might see "Permission denied" errors. Suppress them:

find / -name "filename" 2>/dev/null

The 2>/dev/null sends errors to nowhere.

find vs locate

Command How it works
find Searches filesystem now (slower, current)
locate Searches database (faster, may be outdated)

locate needs periodic updates. find is always accurate.

find vs Spotlight (mdfind)

mdfind "filename"

Uses Spotlight. Faster but limited to indexed locations.

Quick Reference

Command Result
find . -name "*.txt" By name
find . -iname "*.txt" Case insensitive
find . -type f Files only
find . -type d Directories only
find . -size +100M By size
find . -mtime -7 By modification time
find . -name "*.tmp" -delete Find and delete

Keep Learning

find is powerful for file management. The free course covers search and other essential commands.

Check it out at Mac Terminal for Humans.