Linux find command: Comprehensive Guide
The find
command in Linux is a powerful utility for searching and locating files and directories based on conditions you specify.
It can quickly locate files by name, size, type, permissions, date, and many other criteria.
- 1 Basic Syntax
- 2 Finding Files by Name
- 3 Using Regular Expressions
- 4 Finding Files by Type
- 5 Finding Files by Size
- 6 Find Empty Files or Directories
- 7 Finding Files by Date and Time
- 8 Finding Files by Permissions
- 9 Searching for Files with Special Permissions
- 10 Searching by User and Group
- 11 Exclude Directories
- 12 Search for hard links to file
- 13 Combining Multiple Search Criteria
- 14 Limiting Search Depth
- 15 Executing Commands on Files Found
- 16 Using Find with Xargs
- 17 Handling Files with Special Characters
- 18 Using the -sparse
- 19 Printing Results
- 20 Search specific mounted devices (-xdev or -mount)
- 21 The Power of Find Command
- 22 Resource
Basic Syntax
The basic syntax for the find
command is:
find [path...] [expression]
path
: This is where you specify the directory to start the search from. For instance, you can start your search from the root directory (/
) or from your home directory (~
).expression
: This is the condition or criteria to match. For instance, you might search for files by name, size, type, and more.
Output:
$ find /home/user -name myfile.txt /home/user/documents/myfile.txt
This searches the /home/user
directory for a file named myfile.txt
.
Finding Files by Name
Case-sensitive
You can use the -name
option followed by the file name or pattern to search for files by name.
$ find /home/user -name notes.txt /home/user/documents/notes.txt /home/user/backups/notes.txt
This command checks the /home/user
directory for all files named notes.txt
.
Case-insensitive
If you want to perform a case-insensitive search, use the -iname
option.
$ find /home/user -iname Notes.TXT /home/user/documents/notes.txt /home/user/backups/NOTES.txt
Here, the search retrieves files named ‘notes.txt’, ‘NOTES.TXT’, and any other variations in case.
Using Regular Expressions
find
can also match files based on regular expressions, providing a more flexible search pattern.
Using the -regex
The -regex
option searches based on the full path of the file.
$ find /home/user -regex "/home/user/docs/.*\.txt$" /home/user/docs/report.txt /home/user/docs/summary.txt
This command retrieves all .txt
files inside the /home/user/docs
directory.
Using the -iregex
To perform a case-insensitive regex search, use the -iregex
option.
$ find /home/user -iregex "/home/user/DOCS/.*\.txt$" /home/user/docs/report.txt /home/user/DOCS/Overview.TXT
This returns .txt
files from both /home/user/docs
and /home/user/DOCS
directories, regardless of the case.
Read more on how to use regex with Linux find command.
Finding Files by Type
You can use the -type
option followed by a specific code to indicate the file type to search for files based on their type.
To search for regular files, you can use f
code:
$ find /home/user -type f /home/user/file1.txt /home/user/image.png
This lists all regular files in the /home/user
directory.
To search for directories, you can use d
code:
$ find /home/user -type d /home/user/documents /home/user/pictures
This command returns all directories in the /home/user
directory.
To search for symbolic links, you can use the l
code:
$ find /home/user -type l /home/user/link_to_file1.txt
This lists all symbolic links in /home/user
.
Other file types:
b
: block device filesc
: character device filesp
: named pipes (FIFOs)s
: socket files
For example, to find all block device files:
$ find / -type b /dev/sda /dev/sdb
This retrieves all block devices in the system.
Finding Files by Size
To search for files based on their size, you can use the -size
option.
$ find /home/user -size +2M /home/user/movies/sample.mp4 /home/user/backups/backup.tar.gz
This command lists files in the /home/user
directory that are larger than 2 Megabytes.
Understanding size format
The size criteria can be specified using various formats:
c
: bytesk
: kilobytesM
: megabytesG
: gigabytes
The symbol before the size unit indicates the condition:
+
: greater than the specified size-
: less than the specified size- (no symbol): exactly the specified size
$ find /home/user -size -10k /home/user/notes.txt /home/user/config.yaml
This finds files in /home/user
that are smaller than 10 kilobytes.
Find Empty Files or Directories
The -empty
option allows you to locate empty files or directories.
$ find /home/user -type f -empty /home/user/emptyfile.txt /home/user/drafts/untitled.doc
This command lists all empty regular files in the /home/user
directory.
To find empty directories:
$ find /home/user -type d -empty /home/user/drafts/unused_folder
This returns all empty directories within /home/user
.
Finding Files by Date and Time
There are several options you can use with find command to search for files by access date/time or modification date/time.
Search by access time
You can use the -amin
option to search for files accessed in the specified number of minutes.
$ find /home/user -amin -10 /home/user/documents/recently_opened.txt
This command retrieves files in /home/user
accessed within the last 10 minutes.
You can use the -atime
option to search for files accessed in the past ‘n’ days.
$ find /home/user -atime -7 /home/user/documents/week_report.txt
This locates files in /home/user
accessed within the past week.
Search by inode change
You can use -cmin
option to search for files based on inode change time in minutes.
inode includes changes to the file’s metadata, such as its permissions or ownership, but not necessarily its content.
$ find /home/user -cmin -30 /home/user/configs/changed_config.cfg
This command finds files in /home/user
that had their inode changed within the last 30 minutes.
You can use the -ctime
option to search for files based on inode change time in days.
$ find /home/user -ctime -2 /home/user/configs/recently_changed_config.cfg
This locates files in /home/user
that had their inode changed within the past 2 days.
Search by modification time
You can use the -mmin
option to search for files based on modification time in minutes.
$ find /home/user -mmin -15 /home/user/documents/just_edited.txt
This finds files in /home/user
that were modified within the last 15 minutes.
To search for files based on modification time in days, you can use the -mtime
option:
$ find /home/user -mtime -3 /home/user/documents/three_days_ago_edited.txt
This returns files in /home/user
that were modified within the past 3 days.
Find newer files
You can use the -newer
option to find files that are newer than a given file.
$ find /home/user -newer reference.txt /home/user/documents/updated_report.txt
This lists files in /home/user
that are newer than reference.txt
.
Compare timestamps using -newerXY
The -newerXY
option lets you compare the timestamp of files against another file or a specific time. The X and Y can be:
a
: Access timem
: Modification timec
: Inode change timet
: Literal time (specified directly)
For example, to find files modified more recently than they were accessed:
$ find /home/user -neweram reference.txt /home/user/documents/recently_edited_but_not_opened.txt
This command lists files in /home/user
that have a more recent modification time than their access time compared to reference.txt
.
To compare against a specific date, you can use:
$ find /home/user -newermt "2023-08-18" /home/user/documents/post_august_file.txt
This finds files in /home/user
that were modified after August 18, 2023.
Files accessed after modification
The -used
option allows you to search for files based on the number of days between the file’s last access and last modification.
$ find /home/user -used +7 /home/user/old_drafts/draft1.txt
This command lists files in /home/user
that were last accessed more than 7 days after their last modification. Such files might have been modified and then left untouched for a while.
Remember, this doesn’t show you files based on their last accessed time or their modification time directly; rather, it’s showing you files based on the difference in days between those two times.
Finding Files by Permissions
The -perm
option lets you search for files based on their permissions.
$ find /home/user -perm 0755 /home/user/scripts/executable_script.sh
This command lists files in /home/user
with permissions set to 0755
.
You can also use symbolic representation:
$ find /home/user -perm u=rwx,g=rx,o=rx /home/user/scripts/executable_script.sh
This retrieves the same files as the previous command but uses symbolic notation for permissions.
For permissions that match any of the given modes:
$ find /home/user -perm -o=w /home/user/shared/shared_file.txt
This finds files in /home/user
where others have write permission.
Searching for Files with Special Permissions
You can use the -perm
option combined with specific codes to search for files with special permissions, such as the sticky bit, setuid, and setgid.
Sticky Bit
You can use the -1000
code to search for files with the sticky bit set will have the t
in their permissions.
$ find /home/user -perm -1000 /home/user/shared_directory
This finds directories in /home/user
with the sticky bit set.
Setuid
To search for files with the setuid bit set will have the s
in the user’s execute permission, you can use the -4000
code.
$ find /home/user -perm -4000 /home/user/bin/setuid_program
This lists files in /home/user
with the setuid bit set.
Setgid
You can use the -2000
code to search for files with the setgid bit set will have the s
in the group’s execute permission.
$ find /home/user -perm -2000 /home/user/bin/setgid_program
This returns files in /home/user
with the setgid bit set.
Searching by User and Group
To search files based on ownership, you can use the following options:
-user
You can use the -user
option to search for files owned by a specific user.
$ find /home/user -user john /home/user/johns_file.txt
This lists files in /home/user
owned by the user john
.
-group
You can use the -group
option to search for files belonging to a particular group.
$ find /home/user -group developers /home/user/dev/project1.txt
This retrieves files in /home/user
that belong to the developers
group.
-nouser
You can use the -nouser
option to find files that do not have a valid user associated with them.
$ find / -nouser /orphaned_files/file1.txt
This lists files without a valid user owner in the root directory.
-nogroup
You can use the -nogroup
option to find files that do not belong to any valid group.
$ find / -nogroup /orphaned_files/file2.txt
This locates files without a valid group in the root directory.
Exclude Directories
If you need to exclude certain directories from your search, you can use the -prune
option.
$ find /home/user -path '/home/user/excluded_directory' -prune -o -print /home/user/file1.txt /home/user/other_directory/file2.txt
Here, the search avoids the excluded_directory
while printing other results from /home/user
.
Remember: order matters with -prune
. Ensure you specify what to prune before the -o -print
part, or you’ll get unexpected results.
Search for hard links to file
The -samefile
option helps you search for files that point to the same inode as a specified file, essentially finding hard links to that file.
$ find /home/user -samefile /home/user/reference.txt /home/user/reference.txt /home/user/links/reference_hardlink.txt
This command identifies all files in /home/user
that point to the same inode as reference.txt
, which in this case includes the original file and its hard link.
Combining Multiple Search Criteria
Sometimes, you’ll need to search based on multiple conditions. The find
command is flexible enough to combine various search criteria.
Combining Conditions
To find .txt
files modified within the last 3 days:
$ find /home/user -name "*.txt" -mtime -3 /home/user/recently_edited.txt
Using -o (OR)
To search for .txt
or .md
files:
$ find /home/user -name "*.txt" -o -name "*.md" /home/user/note.txt /home/user/readme.md
Using -a (AND)
While -a
is the default, if you want to be explicit, you can use it to combine conditions.
To find .txt
files modified in the last 3 days and larger than 1k:
$ find /home/user -name "*.txt" -a -mtime -3 -a -size +1k /home/user/large_recently_edited.txt
Using ! (NOT)
You can use !
to negate the condition of the search.
To find files that are not .txt
:
$ find /home/user ! -name "*.txt" /home/user/image.jpg
This returns all files in /home/user
that do not have the .txt
extension.
Limiting Search Depth
There are times when you may want to limit the depth of your search. This is where -maxdepth
and -mindepth
come into play.
maxdepth
The -maxdepth
limits the depth of the directory traversal.
$ find /home/user -maxdepth 1 -name "*.txt" /home/user/file1.txt
This finds .txt
files in /home/user
but does not search in subdirectories.
mindepth
The -mindepth
specifies the minimum depth of the directory traversal.
$ find /home/user -mindepth 2 -name "*.txt" /home/user/subdir/file2.txt
This searches for .txt
files in /home/user
but only starting from the second level of directories.
Executing Commands on Files Found
You can take action on the results directly.
Using -exec
The -exec
option allows you to run a command on each found item.
$ find /home/user -name "*.txt" -exec cp {} /home/backup/ \;
This command finds all .txt
files in /home/user
and copies them to the /home/backup/
directory.
Using the -execdir
Similar to -exec
, but executes the specified command in the directory where the matched file resides.
$ find /home/user -name "config.cfg" -execdir mv {} {}.backup \;
This renames all config.cfg
files found in /home/user
to config.cfg.backup
.
Safe Executions with {} + and {} ;
Using {} +
allows multiple file names to be passed as arguments at once.
$ find /home/user -name "*.txt" -exec echo {} + /home/user/file1.txt /home/user/file2.txt
Using {} \;
ensures that the command is executed for each file separately.
$ find /home/user -name "*.txt" -exec echo {} \; /home/user/file1.txt /home/user/file2.txt
Using -delete
The -delete
action enables you to remove files or directories that match your search criteria.
$ find /home/user -name "*.tmp" -delete
The -delete
action processes deletions depth-first, so directories will be emptied of files before the directory itself is removed. This is crucial when working on directories.
Using -delete
can result in data loss. That’s why you need confirmation such as the -ok
action provides.
Confirm action (using -ok)
The -ok
action in the find
command serves as a safeguard when executing commands on found files.
$ find /home/user -name "*.bak" -ok rm {} \; < rm ... /home/user/documents/file1.bak > ? y < rm ... /home/user/documents/file2.bak > ? n
For each file, find
prompts you with the full command it intends to execute (e.g., < rm ... /home/user/documents/file1.bak > ?
).
You must answer with ‘y’ (yes) or ‘n’ (no) for each file. Only files confirmed with ‘y’ are processed.
Using -okdir
Just like -ok
, it prompts the user for confirmation before executing a command.
However, -okdir
executes the specified command from the directory containing the matched file, making it safer for commands that might have unintended consequences if executed with an incorrect path.
$ find /home/user -name "*.bak" -okdir rm {} \; < rm ... file1.bak > ? y < rm ... file2.bak > ? n
Unlike -ok
, which shows the full path, -okdir
shows the filename because the command is executed in the file’s directory.
-ok vs. -okdir
When using -ok
, the command you’re executing is run from the directory where you invoked the find
command. The {}
placeholder will be replaced by the entire path to the matched file.
In contrast, when you use -okdir
, the command is run from the directory containing the matched file, and the {}
placeholder will be replaced by the base name of the matched file (i.e., without the preceding directory path).
So, -okdir
adds a layer of safety.
Using Find with Xargs
xargs
is a powerful tool that reads items from standard input and executes a command on them.
It’s often used with find
to handle filenames and other input.
$ find /home/user -name "*.txt" | xargs tar cvf backup.tar backup.tar /home/user/file1.txt /home/user/file2.txt
This command packs all .txt
files found in /home/user
into a backup.tar
archive.
For filenames with spaces or special characters, it’s safer to use:
$ find /home/user -name "*.txt" -print0 | xargs -0 tar cvf backup.tar
Here, -print0
in find
and -0
in xargs
ensure filenames are treated correctly, even if they contain spaces, newlines, or other special characters.
Handling Files with Special Characters
When working with filenames that contain special characters, like spaces or parentheses, you must ensure they’re handled correctly.
$ find /home/user -name "my file*.txt" /home/user/my file1.txt /home/user/my file2.txt
If you’re scripting or chaining commands, quote the patterns:
$ find /home/user -name "my file*.txt" -exec cat '{}' \; Contents of my file1.txt Contents of my file2.txt
By wrapping {}
in single quotes, you ensure filenames with special characters get passed to the cat
command without issues.
Using the -sparse
The -sparse
option identifies files that are sparsely allocated. Sparse files consume less actual space on disk than their apparent size might suggest.
$ find /home/user -sparse /home/user/large_but_sparse_file.img
This finds files in /home/user
that are sparse. Typically, these files have blocks that read as zero, but don’t consume any space on disk.
Printing Results
By default, find
prints the names of files that meet the specified conditions. However, there are more elaborate methods to print results.
Print file names
The -print
option allows you to prints the full file name.
$ find /home/user -name "sample.txt" /home/user/documents/sample.txt
Format output
The -printf
option allows custom formatting of the output.
$ find /home/user -name "sample.txt" -printf "%f %s bytes\n" sample.txt 1240 bytes
This prints just the filename (%f
) and its size in bytes (%s
), followed by the word “bytes”.
detailed listing
The -ls
option provides a detailed listing similar to ls -l
.
$ find /home/user -name "sample.txt" -ls 1234567 4 -rw-r--r-- 1 user user 1240 Aug 16 12:30 /home/user/documents/sample.txt
The output displays the inode number, size in blocks, file permissions, number of links, owner, group, size in bytes, modification time, and the file name.
Search specific mounted devices (-xdev or -mount)
When working with large filesystems or multiple mount points, limiting the search to a specific filesystem can improve the find
command’s performance.
Both -xdev
and -mount
are the same option, just with different names. This option prevents find
from descending into directories that reside on different file systems (or partitions).
This can be useful if you’re searching a directory like /
(root) but you don’t want to search other mounted filesystems like /boot
or /home
if they’re on separate partitions or devices.
Example: Let’s say you want to find all the .log
files in the /var
directory but not go into other mounted file systems:
$ find /var -xdev -name "*.log"
In this example, if /var/log
was a separate mount point or on a different partition, -xdev
or -mount
would prevent find
from searching within /var/log
.
Note: It’s important to place the -xdev
or -mount
option before any predicates like -name
to ensure it’s treated as an option.
The Power of Find Command
One day, I received an urgent call from the head of the customer service department. They informed me that many customers had reported not receiving their monthly statements.
I quickly pulled up the logs and realized there were over 100,000 files, spread across multiple directories and subdirectories, which contained these statements.
The main issue was that a substantial portion of these files was misnamed, and because of this naming inconsistency, they couldn’t be sent out to the respective customers.
Had this been a manual task, it would have been a disaster. Going through 100,000 files, even with a sizable team, would have taken days if not weeks.
Let’s say, for argument’s sake, that a person could handle 100 files an hour. With eight working hours in a day, that’s 800 files.
To cover 100,000 files, it would require 125 man-days. Even with a team of 10 people, we’d be looking at almost two weeks of work.
This is where the magic of Linux’s find
command came in.
I used a simple command:
$ find /path_to_directory/ -type f -name "wrong_pattern_*"
In no time, it gave me a list of all the misnamed files, regardless of their directory depth. Using the same command, I combined it with a rename operation:
$ find /path_to_directory/ -type f -name "wrong_pattern_*" -exec rename 's/wrong_pattern_/correct_pattern_/' '{}' \;
Within a matter of minutes, all the misnamed files were correctly renamed.
The batch process that sent out the statements was rerun, and within a couple of hours, all the statements were dispatched correctly.
Resource
https://man7.org/linux/man-pages/man1/find.1.html
Mokhtar is the founder of LikeGeeks.com. He is a seasoned technologist and accomplished author, with expertise in Linux system administration and Python development. Since 2010, Mokhtar has built an impressive career, transitioning from system administration to Python development in 2015. His work spans large corporations to freelance clients around the globe. Alongside his technical work, Mokhtar has authored some insightful books in his field. Known for his innovative solutions, meticulous attention to detail, and high-quality work, Mokhtar continually seeks new challenges within the dynamic field of technology.
well done and nicely presented.
Thanks!
Hi good examples
In the last combined example of nice & ionice, in the nice -n , the value is missing.
Thanks for noting that!
Now fixed.