Linux

How the find Command works on Linux

Sponsor

The find command on Linux and Unix like systems (i.e. MacOS) is used to find files and directories in a specific directory. It is one of the most useful commands at your disposal when trying to find and process multiple files. It's also really useful during file audits.

The syntax for find is shown below, where [OPTIONS] are optional settings, [LOCATION] is the location you want to find something within, and [SEARCH TERM] is the file name or directory name you want to find.

find [OPTIONS] [LOCATION] [SEARCH TERM]

How to use the find command on Linux and MacOS

The most basic form of the find command looks like this:

find ./test *.txt

The above command will find any file ending in .txt, i.e. *.txt within the ./test folder. This will return a list of all matching files.

Handling Symbolic Links

Some folders may contain symbolic links that link to another part of your file system. As such, you might unknowingly search a much larger set of folders, if symbolic links do exist. As such, there are a number of options that control what happens when find comes across a symbolic link:

  • -P - when used, symbolic links are never followed.
  • -L - when used, symbolic links are always followed.
  • -H - when used, symbolic links are only followed if mentioned somewhere on the command line, i.e. if you search for link, and there is a symbolic link called link, find will return link along with anything found when following that symbolic link.

Any of these options can be used as shown below:

find -P ./test *.txt

Searching file by type

Since there are many different types of files and directories, it is not always useful to just search for a specific string. If we want to mention the type of file or directory we are looking for, we can specify with the -type option. To remove ambiguity, we also add the -name option before our search string. You can also just remove the search string entirely, and search for a particular file type.

Below, we search for everything with type f, which defines a regular file.

find ./test -type f -name "*.txt"

A full list of all types can be found below:

  • b - block devices
  • c - character devices
  • d - directory
  • p - named pipe (FIFO)
  • f - regular file
  • l - symbolic link - never used if we use the symbolic link -L option.
  • s - socket

Searching by size

We can search by size using the -size option. For example we want to find all files of size 10MB, we use 10M:

find ./test -size 10M

This is not particularly useful, so if we want to find files below or above a certain size, we add - and + respectively. For example, the below will find all files smaller than 10MB.

find ./test -size -10M

As the sizes aren't normal units i.e. mb, gb, kb, the full list of units can be found below:

  • b - 512-byte blocks (default).
  • c - just bytes.
  • w - two-byte words.
  • k - Kilobytes.
  • M - Megabytes.
  • G - Gigabytes.

Find by Owner or Group

Using the -group or -user options, we can also find a directory or file by who owns it, or which group it belongs to. For example, the below code finds all files in the ./test directory where the owner is someOwner:

find ./test -user someOwner

Similarly, we can find by group like so:

find ./test -group someGroup

Find by Permissions

Using -perm, we can find all files with a particular permission combination. The below will find all files in the ./test directory with a permission of 0755. If you want to learn more about permissions, read our article on chmod.

find ./test -perm 0755

Limiting find Command Depth

Since the find command is recursive, it can sometimes return quite a lot of results. If you want to limit the number of levels, then use the -maxdepth option. Similarly, you can use -mindepth to define a minimum depth to go to, before results start to be returned.

find . -name "*.txt" -maxdepth 2

And here is an example with both -mindepth and -maxdepth, which only returns files within a folder within ./test.

find . -name "*.txt" -maxdepth 2 -mindepth 2

Finding Files by Last Accessed/Modified Time

There are a number of different ways to find files based on their last access or modify time. For example, the below command will only find files *.txt in the folder ./test which were last accessed within the last 5 minutes:

find . -name "*.txt" -amin 5

Here, -amin refers to how many minutes ago the file should have been accessed. Here are all the options for checking access/modify time:

  • -amin n - the file was last accessed within n minutes ago.
  • -atime n - the file was last accessed within n days ago.
  • -cmin n - the file status changed within n minutes ago.
  • -ctime n - the file status changed within n days ago.
  • -mmin n - the file was last modified within n minutes ago.
  • -mtime n - the file was last modified within n days ago.
  • -anewer file - the searched for file was modified more recently than [FILE]. If using -L or -H, and [FILE] is a symbolic link, then the file it points to is used.
  • -cnewer file - the searched for file status changed more recently than [FILE]. If using -L or -H, and [FILE] is a symbolic link, then the file it points to is used.

If you add -daystart to the end of any of these, the measurement will be taken from the start of the current day, rather than the current time, i.e. the following will find anything modified within the last 5 days, starting from the beginning of the current day. This option is not available on MacOS.

find . -name "*.txt" -mmin 5 -daystart

Finally, + and - modifications are also available. For instance, -amin -5 will find anything modified in the last 5 minutes, but -amin +5 will find anything modified more than 5 minutes ago.

Executing Commands on find command in Linux and MacOS

Once you find some files or directories with the find command, you might want to do something to them. Thankfully, we can use the -exec option to run commands on each of the files or directories found. Any code after -exec will run on every file found.

For example, the below command will change all found files to have an owner called someOwner.

find . -name "*.txt" -exec chown someOwner {} \;

The \; at the end simply signifies the end of the line. The {} refers to the current file found - find will substitute in the file name for each file found, so that the command is much more secure.

Note: If you want to do this on a directory, then use -execdir instead of -exec.

Delete files with find on Linux and MacOS

It goes without saying that this should be used with caution. find is recursive, and you may unknowingly delete a lot of files you don't intend to. However, if you want to delete files you find with the find command, you can use the -delete flag at the end of your find code. If you put it first, it will delete everything in the folder you specify. So be careful.

The following deletes all files with the form *.txt (i.e. those with a .txt prefix):

find . -name "*.txt" -delete
Last Updated Thursday, 31 March 2022
Johnny Simpson
Johnny Simpson

Subscribe for Daily Dev Tips

Subscribe to our weekly newsletter, to stay up to date with our latest web development and software engineering posts via email. You can opt out at any time.

Not a valid email