The find command in Linux is one of the most versatile utilities for locating files and directories based on complex criteria. Whether we are searching for files by name, size, modification date, permissions, or even content, find provides unparalleled flexibility. It operates recursively through directories, allowing us to pinpoint specific files, execute actions (like deletion or renaming), or apply transformations (such as changing permissions). With options like -name, -size, -mtime, -user, -exec, and -delete, find can handle everything from simple searches to intricate automation tasks. Its ability to integrate with other commands via pipes (|) or -exec makes it indispensable for system administration tasks, including debugging, data management, and automation.

Syntax

find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...] [expression]

More information here or here.

A Few Basic Examples

1. Search by Name

find /usr -name "readme.txt"

Searches for readme.txt in /usr and its subdirectories (both are case-sensitive).

find /usr -iname "*.txt"

Finds all .txt files in /usr and its subdirectories regardless of case (name and extension). For example, this will match license.txt, readme.txt, README.txt, README.TXT, etc.

3. Search by File Extension

find /home -type f -name "*.jpg"

Lists all .jpg files in /home (including subdirectories). The -type f option limits the search to files only, not any type of filesystem object.

4. Find Files Modified in the Last 7 Days

find /var/log -type f -mtime -7

Shows files modified within the last 7 days in /var/log and its subfolders.

5. Find Files Modified in the Last 24 Hours

find /var -newermt "2026-04-03" -type f

Shows files in /var (including subdirectories) modified since yesterday (adjust date as needed).

Alternative command structure to achieve the same could be:

find /var -mtime 0 -type f

6. Find Large Files (e.g., >50MB)

find / -type f -size +50M

Displays files larger than 50MB across the entire filesystem.

7. Find Empty Directories

find /var -type d -empty

Lists all empty directories under /var and its subfolders.

8. Delete Files Older Than 30 Days

find /tmp -type f -mtime +30 -delete

Deletes files in /tmp (and its subfolders) older than 30 days (use with caution!).

9. Search by User Ownership

find /home -type f -user john

Lists all files owned by user john in /home and its subfolders.

10. Find Files with Specific Permissions (e.g., 755)

find /etc -type f -perm 755

Shows files with permissions 755 (equivalent to rwxr-xr-x) in /etc and its subfolders.

11. Find and Count Files in a Directory

find /etc -type f | wc -l

Counts all files in /etc (including subdirectories).

find / -type l -ls

Lists all symbolic links in the system and their targets. In case the targets are not needed, omit the -ls option.

13. Combine Multiple Criteria (e.g., Size + Name)

find /usr -type f -name "*.pdf" -size +5M -size -50M

Finds .pdf files between 5MB and 50MB in /usr and its subfolders.


A Few Extended Examples

1. Search for Files with Specific Text (using grep)

find /var/log -type f -exec grep -l "error" {} \;

Finds .log files containing the word error in /var/log and its subfolders. Note that no actual content is displayed; instead, just the file name is returned.

2. Find and Rename Files

find /data -type f -name "*.old" -exec mv {} {}.bak \;

Search for files with the extension .old in the /data folder and its subfolders and rename them as .old.bak. The mv command can be replaced with cp to create a copy instead of renaming.

3. Find and Delete Temporary Files Older Than 30 Days

find /tmp /var/tmp -type f -name "*.tmp" -mtime +30 -delete

Clean up /tmp and /var/tmp folders and subfolders safely by finding and deleting all .tmp files older than 30 days.

  • Why? Removes old temporary files to free up disk space.
  • Safety: Test first with -print instead of -delete.

4. Find and Compress Large Log Files (>100MB) in /var/log

find /var/log -type f -size +100M -exec gzip {} \;

Prevent log bloat by archiving old logs.

  • Bonus: Add -mtime +7 to target logs older than a week.

5. Find and Restrict Permissions for Sensitive Files

find /etc -type f -user root -perm 777 -exec chmod 644 {} \;

Enforce stricter permissions (644) on files in /etc (and its subfolders) owned by root, with an initial permissions setting of 777.

  • Use Case: Harden system configurations by removing overly permissive settings.
  • Safety: Test first with -print instead of -exec.

6. Find and Copy Specific User Files

find /home -type f -user john -name "*.doc" -mtime +30 -exec cp --parents {} /backup/ \;

Create copies of specific files for backup or migration. In this case, this includes .doc files older than 30 days located in the /home folder and its subfolders owned by the user john.

  • Note: -exec cp --parents preserves directory structure in the backup.

7. Find and Replace Text in Multiple Files

find /var/www/html -type f -name "*.php" -exec sed -i 's/old_value/new_value/g' {} \;

Batch-edit multiple .php files in /var/www/html and its subfolders.

  • Testing: Remove -i to see the changes on the standard out.
  • Warning: Change -i with -i.bak to create copies of the changed files.
find /usr -type l -xtype l

Find broken symlinks in /usr and its subfolders. The result will contain just the list of broken links without information for their missing target objects.

  • Explanation: -xtype l checks for broken symlinks (target doesn’t exist).
  • Addition: Add -ls to see information for the target objects as well.
  • Cleaning: Add -exec rm {} \; to delete the found dangling links.
find /home -xdev -samefile readme.txt

Find all hardlinks for readme.txt in /home and all its subfolders.

  • Explanation: -xdev limits the search to folders on the same filesystem. Alternatively, the -mount option could be used.
  • Note: -samefile could be missing in older versions of the command.

Instead of -samefile, we could use -inum, and then the command would look like:

find /home -xdev -inum 12345

The 12345 value could be obtained via ls -i readme.txt. We could go even further and combine the two commands:

find /home -xdev -inum $(ls -i readme.txt | cur -d ' ' -f 1)

10. Find and Examine Disk Usage by Large Files

find /home -type f -size +1G -printf "%s\t%p\n" | sort -n | tail -n 20

Identify files with size bigger than 1GB in /home and its subfolders.

  • Output: Sorted list (size in bytes, then path) in ascending order of the top 20 largest files.

11. Find Files Owned by Root and Changed in the Last 7 Days

find /etc /var -type f -user root -mtime -7 -exec ls -l {} \; 2>/dev/null

Security audit for suspicious changes to potentially critical files in /etc and /var and their subfolders.

  • Note: The 2>/dev/null addition hides potential error messages from standard output.
find / -type f -name "*.sh" -not -path "/usr/*" -exec chmod +x {} \;

Search for .sh scripts and set their execute permissions in the whole filesystem but skip /usr directory and its subfolders.

  • Note: -not -path excludes specific directories.

Common mistakes

1. Wrong or Missing Starting Directory

Mistake:

find / -name "file.txt"

Or

find -name "file.txt"

Problem:

  • Searches everywhere (including /proc, /sys, /dev), which is slow and may cause permission errors.
  • Searches only in the current folder and may lead to partial results.

Fix:

  • Always explicitly specify a starting directory (e.g., /home, /var, or . for current directory), so the scope is specified and visible:

    find /home -name "file.txt"
    

Note: Using / as the starting directory is not a mistake in itself, as long as we know why we are doing it, i.e. it is the result of a conscious and deliberate action.

2. Using -name Without Wildcards

Mistake:

find /etc -name "config"

Problem:

  • Finds only an exact match (e.g., config file) and misses files like config.txt, config.sh, database.config, etc.

Fix:

  • Use wildcards (e.g., * or ?) for partial matches:

    find /etc -name "*config*"
    

Note: Using -name without wildcards is not a mistake in itself, as long as we know why we are doing it, i.e. it is the result of a conscious and deliberate action.

3. Skipping File Type (-type)

Mistake:

find /var -name "*log*"

Problem:

  • Directories are returned (e.g., logs folder), which may not be wanted and/or cause errors in the selected action (e.g., -exec commands).

Fix:

  • Explicitly target files (-type f) or directories (-type d):

    find /var -type f -name "*log*"
    

Note: Skipping file type is not a mistake in itself, as long as we know why we are doing it, i.e. it is the result of a conscious and deliberate action.

4. Overusing -exec Without -print Testing

Mistake:

find /tmp -name "temp*" -exec rm {} \;

Problem:

  • Deletes files without confirmation which leads to permanent data loss if the command is wrong.
  • No way to preview results before execution.

Fix:

  • Always test with -print first to preview files to delete:

    find /tmp -name "temp*" -print
    
  • Then proceed with -exec:

    find /tmp -name "temp*" -exec rm {} \;
    

Note: The same would apply to all potentially destructive actions, including the -delete one.

5. Wrong Approach to Files with Spaces in Their Name

Mistake:

find /path -name "my file.txt" | xargs rm

Problem:

  • Fails on filenames with spaces or other whitespace characters, as xargs misinterprets them.

Fix:

  • Use -print0 (instead of -print which is used by default) with xargs -0:

    find /path -name "my file.txt" -print0 | xargs -0 rm
    
  • Or with -exec:

    find /path -name "my file.txt" -exec rm {} \;
    

6. Misusing -mtime

Mistake:

find /var/log -type f -mtime 7

Problem:

  • -mtime 7 means “modified exactly 7 days ago” (not “older than 7 days”).
  • -mtime -7 means “modified in the last 7 days” (not “older than 7 days”).
  • -mtime +7 means “modified more than 7 days ago” (correct for old files).

Fix:

  • Use -mtime -7 for “modified in the last 7 days”:

    find /var/log -type f -mtime -7
    
  • Use -mtime +7 for “older than 7 days”:

    find /var/log -type f -mtime +7
    

Note: Depending on the time you are interested in, you can also use -atime and -ctime.

7. Lack of Permissions

Mistake:

find / -type f -name "*.conf"

Problem:

  • It will return multiple “Permission denied” errors and will skip the directories it can’t access (e.g., /root requires sudo).

Fix:

  • Use sudo for restricted directories:

    sudo find /root -type f -name "*.conf"
    
  • Suppress errors with 2>/dev/null (if you don’t need them):

    find /root -type f -name "*.conf" 2>/dev/null
    

8. Forgetting -maxdepth for Shallow Searches

Mistake:

find /etc -type f -name "*.conf"

Problem:

  • Searches every subdirectory, which may not always be necessary.

Fix:

  • Limit depth with -maxdepth (only checks /etc and its immediate children):

    find /etc -maxdepth 2 -name "*.conf"
    

9. Confusing -size Units

Mistake:

find /var -type f -size 100

Problem:

  • find uses 1024-based units (not 1000-based).
  • 100 means exactly 100 512-byte blocks.

Fix:

  • Specify an unit like c for bytes, k for kilobytes (KiB), M for megabytes (MiB), etc.

  • Use - for less than (for example, files smaller than 100KiB):

    find /var -type f -size -100k
    
  • Or + for bigger than (for example, files bigger than 10MiB):

    find /var -type f -size +10M
    

10. Not Escaping Special Characters

Mistake:

find /path -type f -name "file*.txt"

Problem:

  • Finds file.txt, file100.txt, and other similar files, which may be unexpected.
  • * is treated as a wildcard, not a literal *.

Fix:

  • Escape with \ to search for exact match for file*.txt:

    find /path -type f -name "file\*.txt"
    

11. Logic Errors

Mistake:

Two consecutive searches:

find /var -type f -name "*.log"
find /var -type f -name "*.txt"

For “optimization” purposes, they have been merged into one command:

find /var -type f -name "*.log" -name "*.txt"

Problem:

  • The above won’t return anything, even if there are .log and/or .txt files, because a file cannot match two rules simultaneously. There is an implicit logical AND (or -a) operator applied.

Fix:

  • Use -o (OR) to express the desired behaviour correctly:

    find /var -type f -name "*.log" -o -type f -name "*.txt"
    

12. Not Using -regex for Complex Patterns

Mistake:

find /etc -type f -name "*.conf" -o -type f -name "*.cfg"

Problem:

  • Hard to maintain for many patterns.

Fix:

  • Use -regex for regex-based matching:

    find /etc -type f -regex ".*\.\(log\|txt\)"
    

A Few More Tips and Hints

  1. Always start simple with -print
find /path -type f -name "pattern" -print

Then gradually add options (-size, -mtime, -exec, -delete). Always test before acting on files!

  1. Combine with xargs for Efficiency
find /var/log -type f -mtime +30 -print0 | xargs -0 rm -f

Handle filenames with spaces/newlines safely!

  1. Use -maxdepth to Limit Scope
find /etc -type f -maxdepth 2 -name "*.conf" -exec chmod 640 {} \;
  1. Use Redirection
find /var -type f -size +100M -printf "%p\n" > large_files.txt 2> errors.txt
  1. A Few Generic Hints
If you are doing this Then start doing this
Searching / without sudo Use specific starting point or sudo find /
Forgetting -type Always specify -type f or -type d
Using -exec or -delete Test with -print first
Misusing -mtime Remember -mtime -7 (last 7 days), -mtime +7 (older)
Ignoring -print0 Use -print0 + xargs -0 for files with spaces
Forgetting -maxdepth Limit depth with -maxdepth 2 (or another value)
Confusing -size units Remember c (B), k (KB), M (MB), etc. for clarity