find walks directory trees and finds things: files by name, by size, by age, by type — then acts on what it found. Where grep searches inside files, find is the tool for "where is the file itself?".
By name #
Find files by name, case-insensitively
$ find . -name "*.log"
$ find /var -iname "*aospix*"
The search path comes first (. means here), the tests after. Quotes around patterns stop the shell from expanding them before find sees them.
By size, age, and type #
| Test | Matches |
|---|---|
-type f / -type d | Files / directories |
-size +100M | Larger than 100 megabytes |
-mtime +30 | Modified more than 30 days ago |
-mmin -5 | Modified in the last 5 minutes |
-maxdepth 2 | Do not descend deeper than 2 levels |
The large files under /var, with sizes
$ find /var -type f -size +100M -exec ls -lh {} \;
Act on results #
-exec runs a command on every match, with {} standing for the path:
Find and clean up in one pass
$ find . -type f -name "*.tmp" -delete
$ find . -type f -name "*.sh" -exec chmod +x {} \;
-delete is preferred over an exec into rm — it acts only on paths the tests matched, exactly as found.
Combine tests #
Tests are ANDed by default; -o is OR, ! negates:
Config files, excluding anything in node_modules
$ find . -type f \( -name "*.yml" -o -name "*.yaml" \) ! -path "*/node_modules/*"
find pairs naturally with chmod for permission sweeps and with rm for cleanups. More of the terminal notes series is on the journal.
