iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

find

find walks a directory tree, matching by name, size, time, permissions, owner. With -exec or -print0 | xargs it’s a one-liner Swiss-army knife.

find + exec, real recipes

EXAMPLE
# 1) Basics
find .                          # everything under cwd
find /etc -name '*.conf'        # by name (glob)
find . -iname '*readme*'        # case-insensitive
find . -path '*/test/*'         # match path segment
find . -not -path './.git/*'    # exclude git

# 2) By type
find . -type f                  # files only
find . -type d                  # directories only
find . -type l                  # symlinks

# 3) By size
find / -size +100M              # > 100 MiB
find . -size -1k                # < 1 KiB
find . -empty                   # empty files / dirs

# 4) By time — minutes / days / mtime / ctime / atime
find . -mtime -1                # modified < 1 day ago
find . -mtime +30               # modified > 30 days ago
find . -mmin -5                 # modified in last 5 min
find . -newer reference.txt     # modified after this file

# 5) By permissions / owner
find / -perm -4000              # SUID files (audit target)
find . -user ada                # owned by ada
find . -group developers
find . -perm /u+w               # writable by owner

# 6) Combine with logical operators
find . -type f \( -name '*.log' -o -name '*.tmp' \)
find . -type f -name '*.js' -not -path './node_modules/*'

# 7) Act on matches — -exec ; vs +
find . -name '*.tmp' -exec rm {} \;          # one per file (slow)
find . -name '*.tmp' -exec rm {} +            # batched (fast)
find . -name '*.log' -exec gzip {} \;
find . -type f -name '*.txt' -exec grep -l 'TODO' {} +

# 8) Pipe safely with xargs (handles spaces / newlines)
find . -type f -name '*.png' -print0 | xargs -0 du -h | sort -h
find . -type f -name '*.ts'  -print0 | xargs -0 wc -l | tail -1

# 9) Parallel processing
find . -name '*.jpg' -print0 | xargs -0 -P 8 -I {} convert {} -resize 800x600 {}-small.jpg

# 10) Common real recipes
# - Files modified by you in the last day
find . -user "$USER" -mtime -1 -type f

# - Biggest files in a directory
find . -type f -printf '%s %p\n' | sort -nr | head

# - Find files containing TODO with grep -l
find src -type f -name '*.go' -exec grep -l TODO {} +

# - Delete __pycache__ everywhere
find . -type d -name __pycache__ -exec rm -rf {} +

# - Find broken symlinks
find . -xtype l

# - Files with no group / no owner (often left after user deletion)
find / -nouser -o -nogroup 2>/dev/null

# - Files of a specific extension, newest first
find . -name '*.md' -printf '%T@ %p\n' | sort -rn | head

# 11) Modern alternative — fd
# fd 'pattern'                   # like find but smart defaults
# fd -e ts                       # files with extension ts
# fd -H 'config'                 # include hidden files

# 12) Performance
#   • Prune unwanted directories early
#       find . -path ./node_modules -prune -o -type f -name '*.js' -print
#   • Combine -exec ... + over ... \;
#   • Use locate / mlocate when the index is fresh — milliseconds vs seconds

Why it matters

Reach for -exec ... + (or -print0 | xargs -0) over -exec ... \; — one process per batch instead of per file. On a 10k-file find, the speedup is 100×.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
find . -name '*.log' -mtime -1
find . -type f -size +10M
Try it Yourself »

Discussion

Loading…