find File Search

find cheatsheet — search by name, type, size, date, permissions. find . -name '*.log' -mtime +7 -delete. find -exec. Every find expression with real examples.

8 min read

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. find will be available within your WSL environment.
  • Git Bash: If you have Git for Windows installed, Git Bash includes a find command.

Core Concepts

  • Starting Point (Path): The directory where find begins 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.txt in the current directory and its subdirectories:
    find . -name my_document.txt
    
    Searches for files or directories exactly matching my_document.txt.
  • Find files ending with .log in /var/log:
    find /var/log -name "*.log"
    
    Searches for files where the name ends with .log. The wildcard * needs to be quoted to prevent shell expansion.
  • Find files starting with config in your home directory:
    find ~ -name "config*"
    
    Searches for files where the name begins with config.
  • Find files case-insensitively named README:
    find . -iname README
    
    Searches for files matching README, readme, ReadMe, etc.
  • Find directories named src:
    find . -type d -name src
    
    Searches specifically for directories named src.
  • Find files that are NOT named temp.txt:
    find . -type f ! -name temp.txt
    
    Searches for regular files that do not match temp.txt.

Searching by File Type

  • Find all regular files in the current directory:
    find . -type f
    
    Limits results to only regular files.
  • Find all directories:
    find . -type d
    
    Limits results to only directories.
  • Find all symbolic links:
    find . -type l
    
    Limits results to only symbolic links.
  • Find all block special files:
    find . -type b
    
    Limits results to only block special files (like device files).
  • Find all character special files:
    find . -type c
    
    Limits results to only character special files (like device files).
  • Find all named pipes (FIFOs):
    find . -type p
    
    Limits results to only named pipes.
  • Find all sockets:
    find . -type s
    
    Limits results to only sockets.

Searching by Size

  • Find files exactly 10 megabytes in size:
    find . -type f -size 10M
    
    Searches for files precisely 10 MiB. Units: b (512-byte blocks, default), c (bytes), w (two-byte words), k (KiB), M (MiB), G (GiB).
  • Find files larger than 1 gigabyte:
    find . -type f -size +1G
    
    Searches for files greater than 1 GiB.
  • Find files smaller than 500 bytes:
    find . -type f -size -500c
    
    Searches for files less than 500 bytes.
  • Find empty files:
    find . -type f -empty
    
    Finds files that have a size of zero.
  • Find empty directories:
    find . -type d -empty
    
    Finds directories that contain no files or subdirectories.

Searching by Time

  • Find files modified in the last 24 hours:
    find . -mtime -1
    
    Searches for files modified less than 1 day ago. -mtime n means exactly n days ago. +n means more than n days ago.
  • Find files modified exactly 7 days ago:
    find . -mtime 7
    
    Searches for files modified between 724 and 824 hours ago.
  • Find files modified more than 30 days ago:
    find . -mtime +30
    
    Searches for files modified more than 30 days ago.
  • Find files accessed in the last 60 minutes:
    find . -amin -60
    
    Searches for files accessed less than 60 minutes ago. -amin n means exactly n minutes ago. +n means more than n minutes ago.
  • Find files whose data was changed in the last 5 minutes:
    find . -cmin -5
    
    Searches for files whose status (metadata like permissions, ownership) or content was changed less than 5 minutes ago.
  • Find files modified more recently than another_file.txt:
    find . -newer another_file.txt
    
    Searches for files with a modification time newer than another_file.txt.

Searching by Permissions and Ownership

  • Find files with read and write permissions for the owner (600):
    find . -perm 600
    
    Searches for files with exactly these permissions.
  • Find files that are executable by anyone:
    find . -perm /a+x
    
    Searches for files where the "execute" bit is set for any category (user, group, or others). /mode means any of the bits in mode are set.
  • Find files that are readable, writable, and executable by the owner:
    find . -perm -u=rwx
    
    Searches for files where all of the specified permission bits are set for the owner. -mode means all of the bits in mode are set.
  • Find files owned by user johndoe:
    find . -user johndoe
    
    Searches for files owned by the user johndoe.
  • Find files belonging to the group developers:
    find . -group developers
    
    Searches for files belonging to the group developers.

Performing Actions on Found Files

  • Print the names of all .conf files (default action):
    find . -name "*.conf" -print
    
    Explicitly prints the full path of each found file. -print is often implied if no other action is specified.
  • Delete all files named *.tmp:
    find . -name "*.tmp" -delete
    
    Deletes found files. Use with extreme caution!
  • Execute ls -l on all .sh files:
    find . -name "*.sh" -exec ls -l {} \;
    
    Runs ls -l for each found .sh file. {} is replaced by the filename, and \; terminates the command.
  • Execute chmod 644 on all .txt files:
    find . -name "*.txt" -exec chmod 644 {} \;
    
    Changes permissions for each found .txt file.
  • Execute grep "ERROR" on all .log files:
    find . -name "*.log" -exec grep "ERROR" {} \;
    
    Searches for the string "ERROR" within each .log file.
  • Execute rm on multiple files at once (more efficient):
    find . -name "*.bak" -exec rm {} +
    
    Runs rm with multiple filenames as arguments, which is often faster than \;.
  • Find and archive all .jpg files into images.tar:
    find . -name "*.jpg" -exec tar -rf images.tar {} +
    
    Appends found .jpg files to an archive.
  • Find files owned by olduser and change ownership to newuser:
    find . -user olduser -exec chown newuser {} \;
    
    Changes the owner of files.
  • List details of all directories:
    find . -type d -exec ls -ld {} \;
    
    Uses ls -ld to show directory details without listing contents.

Controlling Search Depth

  • Search only in the current directory (no subdirectories):
    find . -maxdepth 1 -name "*.conf"
    
    Limits the search to the starting directory only.
  • Search up to 3 levels deep:
    find . -maxdepth 3 -name "myfile.txt"
    
    Searches the current directory and its subdirectories down to a depth of 3.
  • Search starting from depth 2 (skip current and first level):
    find . -mindepth 2 -name "*.log"
    
    Starts searching from the second level of subdirectories.
  • Search between depth 2 and 4:
    find . -mindepth 2 -maxdepth 4 -name "data*"
    
    Searches only within the specified depth range.

Combining Expressions (Operators)

  • Find files named *.txt OR *.md:
    find . \( -name "*.txt" -o -name "*.md" \)
    
    Uses -o for 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:
    find . -type f -size +1M -mtime -7
    
    By default, expressions are joined by -and.
  • Find files that are NOT owned by root:
    find . ! -user root
    
    Uses ! for NOT (or -not).

Common Patterns

  • Find and delete empty directories:
    find . -type d -empty -delete
    
  • Find all .git directories 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):
    find / -type f -perm /u=s -ls
    
    The -ls action provides ls -dils style 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 -name and -iname arguments (e.g., *.txt) to prevent the shell from expanding them before find sees them.
  • -exec with \; 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 your find command without -delete first to ensure it matches only the files you intend to remove.
  • Default Path: If no starting path is given, find searches the current directory (.).
  • Permissions: find needs 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 -1 means "less than one 24-hour period ago" (i.e., within the last 24 hours). -mtime 1 means "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, find does not follow symbolic links when searching unless explicitly told to (e.g., with -L). The -type l test finds the links themselves, not the files they point to. Use -L before the path to make find follow symbolic links.