How to Find Files in Linux?
Everyone has at one point forgotten where they've kept something, or where they last saw something, and this extends to files and folders on our computers as well.
When we want to find a file, we can lose precious time by going through all folders we last remember where our file is, or rely on handy Linux tools, such as find
, locate
, or even fzf
.
This tutorial would be covering the use of the find
program, and how to use some of the numerous options to speed up the process.
find
is a handy Linux utility, a great tool in the arsenal of a SysAdmin, and time-saving if used properly. It can be combined with tools such as grep
or sed
, to further speed up the process. The program searches for files and directories in a directory hierarchy based on an expression given by the user, and with the help of command-line flags, performs user-specified actions on the matches as well.
With the manipulation of the flags, you can use find
to search for files based on the user, group, last edited date, type, size, and more.
find
Command Syntax
find [OPTIONS] [STARTING-POINT] [EXPRESSION]
- OPTIONS: It controls how symbolic links are treated, debug options and optimization levels.
- STARTING-POINT: Path at which to start searching and recursively descend.
- EXPRESSION: This specifies the expression which matches the file to search for, regex type, depth of recursive search, and other such options.
To search for any files, the user needs to read permissions for that directory.
Let's say we want to search for all HTML
files in a folder, at a maximum depth of 3 from our starting point, we would write the following,
find Documents/ -maxdepth 3 -name '*.html'
The above command runs in the following manner
- We start searching at the
Documents
folder from our current directory
- The program should traverse at most a depth of 3 directories from its current position
- It searches for all
HTML
files, with any number of characters in its name
To make the search case insensitive, for example, to search for files ending in HTML
, instead, of html
we can use the -iname
flag instead of -name
where the i means case insensitive.
Now to cover some of the most essential flags of the find
command, that has not been explained above
-not
:
find Documents/ -maxdepth 3 -not -name '*.html'
For our example above, all files not matching the specified pattern would be returned, hence we could get a JPG file as a result.
-
-type
:
This specifies the kind of object we are searching for. It is of the form -type c
, where c
can be one of the multiple values, but the one used by a regular user would be f
, l
, and d
.
f
represents a file, d
represents a directory, and l
a symbolic link. Hence,
find Documents/ -maxdepth 3 -type f -name '*git*' # Files having the word git in name
find Documents/ -maxdepth 3 -type d -name '*git*' # Folders having the word git in name
find Documents/ -maxdepth 3 -type l -name '*git*' # Symbolic links having the word git in name
-
-size
:
Find files by their size. The flag is of the form -size [+-]n[cwbkMG]
( characters within [] are optional, and means that one of these characters are to be used ). The meaning of the characters is as follows
Character |
Meaning |
± ( Absence means exact file size ) |
+ - Files greater than the specified size |
- - Files smaller than the specified size |
n |
File size |
c |
Bytes |
w |
Two-byte words |
b |
512-byte blocks ( default ) |
k |
Kibibytes ( unit of 1024 bytes ) |
M |
Mebibytes ( units of 1024 * 1024 = 1048576 bytes ) |
G |
Gibibytes ( units of 1024 * 1024 * 1024 = 1073741824 bytes ) |
The sizes are not rounded. That means a size of -1M
is not the same as -1048576c
, hence, the former would match only empty files, while the latter would match all files having a size smaller than 1048576 bytes. To search for files within a range you could use a command like the following
find -type f -size +40M -size 60M # Returns all files with 40 < fileSize <= 60 M
-
-mtime
and -daystart
:
-mtime
is of the form -mtime [+-]n
, where n represents n * 24
hours. ±
holds the same meaning as it does in -size
. -daystart
is used to make time measurement start from the start of the current day, instead of from 24 hours ago.
Hence to find a file edited less than 5 days ago, from the start of today, we would use
find -type f -mtime -5 -daystart
-
-perm
:
To find files by permission we use -perm
. If -perm
is used as is it will match the exact permissions, for example -perm 664
, would match all files with RW permissions for users, and groups, but only read permissions for others. If the permission number is prepended by a /
, it ensures that at least one of the permissions ( Users, Groups, or Others ) matches. If the permission number is prepended by a -
, it ensures that at least those bits are set, and it doesn't matter if more are set. Hence, if we search for a file with the flag as -perm -117
, if the file has permissions as 777, it would return that file as a true match.
-
-user
and -group
:
-
-user
is used to find all files owned by a specific user, by providing either the username or UID
-
-group
is used to find files owned by a group, using either group or GID
Hence, to search for all files owned by a user with UID 1000, and Group docker, we would run
find -executable -user 1000 -group docker
-
-delete
:
This option deletes all the files that return true, for the given expression.
-
-execdir
and -executable
:
-execdir
is used to execute a command on the files, and/or directories that match the options and patterns specified by the user to run a command. The string {}
is expanded to the current filename, and the specified command is run once for each file. All following text is considered a command, till a ;
is not encountered. To avoid expansion by the shell, these strings should be quoted, or escaped with the \
character. -executable
on the other hand, is used to match executable files.
Conclusion
This tutorial has covered the find
command, and how to utilise it to search for files, and/or directories in your filesystem. It also covers how to optimize your searches, and how you can run commands on the file, without making a secondary list.