find is one of the great utilities in the UNIX/Linux command-line toolbox.
The find command uses the following strategy: find descends through a hierarchy of files, matches the files that meet specified criteria, and performs some actions.
In order to list all the files and folders from the current directory to the descending child directories, use the following syntax:
find base_path
base_path can be any location from which the find should start descending. An example of this command is as follows:
find . -print
. specifies current directory and .. specifies the parent directory. This convention is followed throughout the UNIX file system.
The -print argument specifies to print the names (path) of the matching files. When -print is used ‘\n’ will be the delimiting character for separating each file.
The -print0 argument specifies each matching file name printed with the delimiting character ‘\0’. This is useful when a filename contains a space character.
Search based on file name or regular expression match
The -name argument specifies a matching string for the filename. We can pass wildcards as its argument text. *.txt matches all the filenames ending with .txt and prints them.
find /home/administrator/example -name "*.txt" -print
The find command has an option –iname (ignore case), which is similar to -name. –iname matches the name ignoring the case.
For example:
find . -iname "example*" -print
If we want to match either of the multiple criterions, we can use OR conditions as shown below:
find . \( -name "*.txt" -o -name "*.png" \) -print
The -path argument can be used to match the file path for files that match the wildcards. -name always matches using the given filename. However, -path matches the file path as a whole. For example:
find /home/administrator -path "*image*" -print
The -regex argument is similar to -path, but -regex matches the file paths based on regular expressions.
The following command matches .png or .jpg files:
find . -regex ".*\(\.png\|\.jpg\)$"
Similarly, using -iregex ignores the case for the regular expressions that are available. For example:
find . -iregex ".*\(\.png\|\.jpg\)$"
Negating arguments
find can also take negation of arguments using “!”. For example:
find . ! -name "*.txt" -print
Search based on the directory depth
We can restrict the depth to which the find command traverses using some depth parameters given to the find. -maxdepth and -mindepth are the parameters.
find . -maxdepth 1 -type f -print
This command lists all the regular files only from the current directory. If there are subdirectories, they are not printed or traversed. Similarly, -maxdepth 2 traverses up to at most two descending levels of subdirectories.
-mindepth is similar to –maxdepth, but it sets the least depth level for the find traversal.
find . -mindepth 2 -type f -print
Search based on file type
The file search can be filtered out using the -type option. By using –type, we can specify to the find command that it should only match files having a specified type.
List only directories including descendants as follows:
find . -type d -print
List only regular files as follows:
find . -type f -print
List only symbolic links as follows:
find . -type l -print
Search on up file times
Print all the files that were accessed within the last 7 days as follows:
find . -type f -atime -7 -print
Print all the files that are having access time exactly 7 days old as follows:
find . -type f -atime 7 -print
Print all the files that are having access time older than 7 days as follows:
find . -type f -atime +7 -print
Similarly, we can use the –mtime parameter for search files based on modification time and -ctime for search based on change time.
- -amin (access time)
- -mmin (modification time)
- -cmin (change time)
Search based on file size
Print all the files that are having size greater than 2 kilobytes
find . -type f -size +2k
Print all the files that are having size less than 2 kilobytes
find . -type f -size -2k
Print all the files that are having size 2 kilobytes
find . -type f -size 2k
Deleting based on the file matches
The -delete flag can be used to remove files that are matched by find.
Remove all the .jpg files from the current directory as follows:
find . -type f -name "*.jpg" -delete
Match based on the file permissions and ownership
It is possible to match files based on the file permissions. We can list out the files having specified file permission as follows:
find . -type f -perm 777 -print
We can also search files based on ownership of the files. The files owned by a specific user can be found out using the -user USER option.
find . -type f -user root -print
Executing commands or actions with find
The find command can be coupled with many of the other commands using the -exec option. -exec is one of the most powerful features that comes with find.
Let’s have a look at the following example:
sudo find . -type f -user administrator -exec chown root {} \;
Skip specified directories from the find
Skipping certain subdirectories for a performance improvement is sometimes required while doing a directory search and performing some action
find . \( -name "*.txt" -prune \) -o \( -type f -print \)
Here, \( -name “*.txt” -prune \) is the exclude portion