find

Search for files and directories by name, type, size, time, permissions, and more.

What it does

find walks a directory tree and evaluates each file or directory against tests you specify. When something matches, it can print the path, run an action, delete it, or pass it to another command.

How it works (mechanical)

Quick Start

# Find a file by exact name in current directory tree
find . -name "notes.txt"

# Find directories only
find . -type d

# Find files only
find . -type f

Core Options (Most Useful Flags)

-name "PATTERN"      Match name (case-sensitive)
-iname "PATTERN"     Match name (case-insensitive)
-type f              Files only
-type d              Directories only
-type l              Symlinks only
-size +100M          Larger than 100 MB
-size -10k           Smaller than 10 KB
-mtime -7            Modified within last 7 days
-mtime +30           Modified more than 30 days ago
-user USER           Owned by user
-group GROUP         Owned by group
-perm 644            Exact permissions
-perm -u+w           Has writable bit for user
-maxdepth N          Limit recursion depth
-mindepth N          Skip top levels
-empty               Empty files or directories
-delete              Delete matched items
-print               Print matched paths
-exec CMD {} \;      Run command once per match
-exec CMD {} +       Run command with many matches at once

Pattern & Logic Notes

# OR logic
find . \( -name "*.log" -o -name "*.tmp" \)

# AND logic (implicit)
find . -type f -name "*.txt"

# NOT logic
find . ! -name "*.txt"

# Case-insensitive name match
find . -iname "*report*"

Important: parentheses usually need escaping in the shell: \( and \).

12 Practical Examples

# 1) Find a specific file by name
find . -name "config.yaml"
# 2) Find all .txt files
find . -type f -name "*.txt"
# 3) Find directories named cache
find . -type d -name "cache"
# 4) Case-insensitive search
find . -iname "*invoice*"
# 5) Find files bigger than 500 MB
find . -type f -size +500M
# 6) Find files modified in last 2 days
find . -type f -mtime -2
# 7) Find files older than 30 days
find . -type f -mtime +30
# 8) Find empty files
find . -type f -empty
# 9) Find empty directories
find . -type d -empty
# 10) Find by permissions
find . -type f -perm 644
# 11) Find and delete .tmp files
find . -type f -name "*.tmp" -delete
# 12) Find and run a command on matches
find . -type f -name "*.log" -exec ls -lh {} \;

Very Useful Real-World Examples

# Find files and search inside them with grep
find . -type f -name "*.txt" -exec grep -H "ERROR" {} \;
# Better for many files: use grep directly if it supports recursion
grep -r "ERROR" .
# Find all shell scripts
find . -type f -name "*.sh"
# Find broken symlinks
find . -xtype l
# Limit search depth
find . -maxdepth 2 -type f
# Skip the top directory itself
find . -mindepth 1 -type d
# Find files owned by a user
find /var/www -user apache
# Find world-writable files
find . -type f -perm -0002
# Find then remove empty directories
find . -type d -empty -delete
# Find and copy results elsewhere using xargs
find . -type f -name "*.conf" | xargs -I{} cp "{}" /tmp/config-backup/

Notes & Gotchas

Safety Pattern

# SAFEST workflow:
# 1) print matches first
find . -type f -name "*.tmp" -print

# 2) only then delete
find . -type f -name "*.tmp" -delete

That one habit prevents a lot of pain.

Historical Context

find has been a core Unix tool for decades. It became essential because Unix systems treat nearly everything as files, and administrators needed a precise way to search large directory trees and act on the results.

Modern Equivalent

Modern tools like fd offer simpler syntax and faster defaults for common searches, but find remains the standard because it is widely available and far more powerful for complex filtering and actions.

Related Commands