What it is
find is a command-line utility for searching for files and directories within a directory hierarchy based on various criteria like name, type, size, modification time, and permissions.
Installation
find is a standard Unix utility and is pre-installed on most Linux and macOS systems.
For Windows, you can install it via:
- WSL (Windows Subsystem for Linux): Install a Linux distribution from the Microsoft Store.
findwill be available within your WSL environment. - Git Bash: If you have Git for Windows installed, Git Bash includes a
findcommand.
Core Concepts
- Starting Point (Path): The directory where
findbegins its search. If not specified, it defaults to the current directory (.). - Expressions: The set of criteria used to filter files. Expressions consist of options, tests, actions, and operators.
- Tests: Conditions that files must meet to be selected (e.g.,
-name,-type,-size). - Actions: What to do with the files that match the tests (e.g.,
-print,-exec,-delete). - Operators: How to combine multiple tests and actions (e.g.,
-and,-or,-not).
Commands / Usage
Searching by Name and Path
- Find files named
my_document.txtin the current directory and its subdirectories:
Searches for files or directories exactly matchingfind . -name my_document.txtmy_document.txt. - Find files ending with
.login/var/log:
Searches for files where the name ends withfind /var/log -name "*.log".log. The wildcard*needs to be quoted to prevent shell expansion. - Find files starting with
configin your home directory:
Searches for files where the name begins withfind ~ -name "config*"config. - Find files case-insensitively named
README:
Searches for files matchingfind . -iname READMEREADME,readme,ReadMe, etc. - Find directories named
src:
Searches specifically for directories namedfind . -type d -name srcsrc. - Find files that are NOT named
temp.txt:
Searches for regular files that do not matchfind . -type f ! -name temp.txttemp.txt.
Searching by File Type
- Find all regular files in the current directory:
Limits results to only regular files.find . -type f - Find all directories:
Limits results to only directories.find . -type d - Find all symbolic links:
Limits results to only symbolic links.find . -type l - Find all block special files:
Limits results to only block special files (like device files).find . -type b - Find all character special files:
Limits results to only character special files (like device files).find . -type c - Find all named pipes (FIFOs):
Limits results to only named pipes.find . -type p - Find all sockets:
Limits results to only sockets.find . -type s
Searching by Size
- Find files exactly 10 megabytes in size:
Searches for files precisely 10 MiB. Units:find . -type f -size 10Mb(512-byte blocks, default),c(bytes),w(two-byte words),k(KiB),M(MiB),G(GiB). - Find files larger than 1 gigabyte:
Searches for files greater than 1 GiB.find . -type f -size +1G - Find files smaller than 500 bytes:
Searches for files less than 500 bytes.find . -type f -size -500c - Find empty files:
Finds files that have a size of zero.find . -type f -empty - Find empty directories:
Finds directories that contain no files or subdirectories.find . -type d -empty
Searching by Time
- Find files modified in the last 24 hours:
Searches for files modified less than 1 day ago.find . -mtime -1-mtime nmeans exactly n days ago.+nmeans more than n days ago. - Find files modified exactly 7 days ago:
Searches for files modified between 724 and 824 hours ago.find . -mtime 7 - Find files modified more than 30 days ago:
Searches for files modified more than 30 days ago.find . -mtime +30 - Find files accessed in the last 60 minutes:
Searches for files accessed less than 60 minutes ago.find . -amin -60-amin nmeans exactly n minutes ago.+nmeans more than n minutes ago. - Find files whose data was changed in the last 5 minutes:
Searches for files whose status (metadata like permissions, ownership) or content was changed less than 5 minutes ago.find . -cmin -5 - Find files modified more recently than
another_file.txt:
Searches for files with a modification time newer thanfind . -newer another_file.txtanother_file.txt.
Searching by Permissions and Ownership
- Find files with read and write permissions for the owner (600):
Searches for files with exactly these permissions.find . -perm 600 - Find files that are executable by anyone:
Searches for files where the "execute" bit is set for any category (user, group, or others).find . -perm /a+x/modemeans any of the bits in mode are set. - Find files that are readable, writable, and executable by the owner:
Searches for files where all of the specified permission bits are set for the owner.find . -perm -u=rwx-modemeans all of the bits in mode are set. - Find files owned by user
johndoe:
Searches for files owned by the userfind . -user johndoejohndoe. - Find files belonging to the group
developers:
Searches for files belonging to the groupfind . -group developersdevelopers.
Performing Actions on Found Files
- Print the names of all
.conffiles (default action):
Explicitly prints the full path of each found file.find . -name "*.conf" -print-printis often implied if no other action is specified. - Delete all files named
*.tmp:
Deletes found files. Use with extreme caution!find . -name "*.tmp" -delete - Execute
ls -lon all.shfiles:
Runsfind . -name "*.sh" -exec ls -l {} \;ls -lfor each found.shfile.{}is replaced by the filename, and\;terminates the command. - Execute
chmod 644on all.txtfiles:
Changes permissions for each foundfind . -name "*.txt" -exec chmod 644 {} \;.txtfile. - Execute
grep "ERROR"on all.logfiles:
Searches for the string "ERROR" within eachfind . -name "*.log" -exec grep "ERROR" {} \;.logfile. - Execute
rmon multiple files at once (more efficient):
Runsfind . -name "*.bak" -exec rm {} +rmwith multiple filenames as arguments, which is often faster than\;. - Find and archive all
.jpgfiles intoimages.tar:
Appends foundfind . -name "*.jpg" -exec tar -rf images.tar {} +.jpgfiles to an archive. - Find files owned by
olduserand change ownership tonewuser:
Changes the owner of files.find . -user olduser -exec chown newuser {} \; - List details of all directories:
Usesfind . -type d -exec ls -ld {} \;ls -ldto show directory details without listing contents.
Controlling Search Depth
- Search only in the current directory (no subdirectories):
Limits the search to the starting directory only.find . -maxdepth 1 -name "*.conf" - Search up to 3 levels deep:
Searches the current directory and its subdirectories down to a depth of 3.find . -maxdepth 3 -name "myfile.txt" - Search starting from depth 2 (skip current and first level):
Starts searching from the second level of subdirectories.find . -mindepth 2 -name "*.log" - Search between depth 2 and 4:
Searches only within the specified depth range.find . -mindepth 2 -maxdepth 4 -name "data*"
Combining Expressions (Operators)
- Find files named
*.txtOR*.md:
Usesfind . \( -name "*.txt" -o -name "*.md" \)-ofor OR. Parentheses\(and\)are needed for grouping and must be escaped. - Find files that are larger than 1MB AND were modified in the last 7 days:
By default, expressions are joined byfind . -type f -size +1M -mtime -7-and. - Find files that are NOT owned by
root:
Usesfind . ! -user root!for NOT (or-not).
Common Patterns
- Find and delete empty directories:
find . -type d -empty -delete - Find all
.gitdirectories and remove them:find . -type d -name ".git" -exec rm -rf {} \; - Find all files larger than 100MB and list them with details:
find . -type f -size +100M -exec ls -lh {} \; - Find all files modified in the last 2 days and copy them to a backup directory:
mkdir ~/backup_today find . -type f -mtime -2 -exec cp {} ~/backup_today/ \; - Find all files owned by a specific user and change ownership:
find /data -user olduser -exec chown newuser:newgroup {} \; - Find all files with the SUID bit set (potential security risk):
Thefind / -type f -perm /u=s -ls-lsaction providesls -dilsstyle output. - Find all files and count them:
find . -type f | wc -l - Find all empty files and delete them:
find . -type f -empty -delete - Find files older than a year and archive them:
find /archive/logs -type f -mtime +365 -exec tar -rf /archive/old_logs.tar {} + - Find files that are not readable by anyone:
find . -type f ! -readable -ls
Gotchas
- Shell Globbing: Always quote wildcards (
*,?,[]) in-nameand-inamearguments (e.g.,*.txt) to prevent the shell from expanding them beforefindsees them. -execwith\;vs+:\;executes the command once for each file found. This can be slow if many files are found.+executes the command with as many filenames as possible passed as arguments at once. This is generally more efficient.
-delete: This action is powerful and irreversible. Always test yourfindcommand without-deletefirst to ensure it matches only the files you intend to remove.- Default Path: If no starting path is given,
findsearches the current directory (.). - Permissions:
findneeds read and execute permissions on directories to traverse them. If it encounters a directory it cannot access, it will print an error message and skip it. -mtime,-atime,-ctime: These time-based tests work in units of 24-hour periods.-mtime -1means "less than one 24-hour period ago" (i.e., within the last 24 hours).-mtime 1means "exactly one 24-hour period ago" (i.e., between 24 and 48 hours ago).- File Name Collisions: When using
-exec ... {} +, be aware that the command might be executed with a very long list of arguments, potentially exceeding system limits. This is rare but possible. - Symbolic Links: By default,
finddoes not follow symbolic links when searching unless explicitly told to (e.g., with-L). The-type ltest finds the links themselves, not the files they point to. Use-Lbefore the path to makefindfollow symbolic links.