How to use Find and Locate to search for files in Linux

0 Shares
0
0
0
0

Introduction

One of the problems that users face when first learning how to work with Linux is how to find the files they are looking for. This guide will show you how to use the command find It covers the proper name. It helps you search for files on your system using various filters and parameters. It also briefly describes the command locate which can be used to search for files in a different way.

Prerequisites
  • To follow this guide, you will need access to a computer running a Linux-based operating system. This can be a virtual private server that you connect to with SSH or your local machine. Note that this tutorial was verified using a Linux server running Ubuntu 20.04, but the examples provided should work on a computer running any version of any Linux distribution.

Find by name

The most obvious way to search for files is by their name. To find a file by name with the command find, you should use the following command:

find -name "query"

This will be case-sensitive, meaning that searching for the query will be the same as searching for Query It's different. To find a file by name but ignore the case of the query, use the -iname option:

find -iname "query"

If you want to find all files that do not adhere to a specific pattern, you can narrow the search with -not Reverse:

find -not -name "query_to_avoid"

Alternatively, you can reverse the search using an exclamation mark (!), like this:

find \! -name "query_to_avoid"

Note that if you use !, you must escape the character with a backslash (\) before you can use it. find can interpret it, the shell does not try to interpret it.

Find by type

With parameter -type You can specify the types of files you want to find. Here's how it works:

find -type type_descriptor query

Here are some descriptors you can use to determine the file type:

  • f: Regular file
  • d: directory
  • l: symbolic link
  • c: Character devices
  • b: Blocks devices

For example, if you want to find all the character devices on your system, you can issue this command:

find /dev -type c

This command specifically only searches for devices in the /dev folder, the directory where device files are typically installed on Linux systems:

Output
/dev/vcsa5
/dev/vcsu5
/dev/vcs5
/dev/vcsa4
/dev/vcsu4
/dev/vcs4
/dev/vcsa3
/dev/vcsu3
/dev/vcs3
/dev/vcsa2
/dev/vcsu2
/dev/vcs2
. . .

You can view all the files that .conf Search for files ending in . This example will find matching files in the folder /usr Searches for:

find /usr -type f -name "*.conf"
Output
/usr/src/linux-headers-5.4.0-88-generic/include/config/auto.conf
/usr/src/linux-headers-5.4.0-88-generic/include/config/tristate.conf
/usr/src/linux-headers-5.4.0-90-generic/include/config/auto.conf
/usr/src/linux-headers-5.4.0-90-generic/include/config/tristate.conf
/usr/share/adduser/adduser.conf
/usr/share/ufw/ufw.conf
/usr/share/popularity-contest/default.conf
/usr/share/byobu/keybindings/tmux-screen-keys.conf
/usr/share/libc-bin/nsswitch.conf
/usr/share/rsyslog/50-default.conf
. . .

Filter by time and size

find It provides you with different ways to filter results by size and time.

Size

Using the parameter -size You can filter files based on their size. To do this, you need to add a special suffix to the end of a numeric size value to indicate whether you are counting the size in bytes, megabytes, gigabytes, or some other measure. Here are some commonly used size suffixes:

  • c: bytes
  • k: kilobyte
  • m: megabyte
  • g: gigabyte
  • b: 512-byte blocks

To illustrate, the following command will find any file in the /usr directory that is exactly 50 bytes long:

find /usr -size 50c

To find files that are less than 50 bytes, you can use this syntax:

find /usr -size -50c

To find files in the /usr folder that are larger than 700 MB, you can use this command:

find /usr -size +700M
Time

For each file on the system, Linux stores timestamps for access time, modification time, and modification time.

  • Access time: The last time a file was read or written.
  • Modification time: The last time the file contents were modified.
  • Modification time: The last time the file's inode metadata was changed.

Using the options atime- ,mtime- and -ctime, you can base your Find searches on these parameters. For each of these options, you must pass a value that indicates how many days in the past you want to search. Similar to the size options described earlier, you can precede these options with plus or minus signs to specify "greater than" or "less than.".

For example, to find files in the /usr folder that were modified in the past day, run the following command:

find /usr -mtime 1

If you want files that you accessed less than a day ago, you can run this command:

find /usr -atime -1

To find files whose metadata was last changed more than 3 days ago, you can run the following:

find /usr -ctime +3

These options also have accompanying parameters that you can use to specify minutes instead of days:

find /usr -mmin -1

This will show the files that were modified last time.

find It can also compare to a reference file and return newer items:

find / -newer reference_file

This syntax returns any file on the system that has been created or changed recently relative to the reference file.

Find by owner and permissions

You can also search for files by the user or group that owns the file using the -user and -group parameters. To find any file in the /var directory that is owned by the syslog user, run this command:

find /var -user syslog

Similarly, you can list files in the /etc directory that belong to the shadow group by typing:

find /etc -group shadow

You can also search for files with specific permissions.

If you want to match an exact set of permissions, you can use this syntax, which specifies permissions using octal notation:

find / -perm 644

This matches files exactly with the specified permissions.

If you want to specify something with at least these permissions, you can precede the permissions symbol with a minus sign:

find / -perm -644

This matches any file that has additional permissions. A file with permissions of 744 in this example matches.

Filtering by depth

In this section, you will create a sample directory structure that you will then use to examine filtering files based on their depth in the structure. If you are following the examples in this tutorial, it is wise to create these files and directories in the /tmp/ folder. /tmp/ is a temporary directory, meaning that any files and directories in it will be deleted the next time the server boots. This will be useful for the purposes of this guide, as you can create as many directories, files, and links as you want without worrying about them crashing your system later. After running the commands in this section, your /tmp/ directory will contain three levels of directories, with ten directories at the first level. Each directory (including the temporary directory) will contain ten files and ten subdirectories.

Create a sample directory structure in the /tmp/ folder with the following command:

mkdir -p /tmp/test/level1dir{1..10}/level2dir{1..10}/level3dir{1..10}

After that, populate these directories with some sample files using the touch command:

touch /tmp/test/{file{1..10},level1dir{1..10}/{file{1..10},level2dir{1..10}/{file{1..10},level3dir{1..10}/file{1..10}}}}

With these files and directories in place, go ahead and change to the test/ directory you just created:

cd /tmp/test

To get a basic understanding of how to retrieve files from this structure, start by searching for the regular name that matches any file named file1:

find -name file1
Output
./level1dir7/level2dir8/level3dir9/file1
./level1dir7/level2dir8/level3dir3/file1
./level1dir7/level2dir8/level3dir4/file1
./level1dir7/level2dir8/level3dir1/file1
./level1dir7/level2dir8/level3dir8/file1
./level1dir7/level2dir8/level3dir7/file1
./level1dir7/level2dir8/level3dir2/file1
./level1dir7/level2dir8/level3dir6/file1
./level1dir7/level2dir8/level3dir5/file1
./level1dir7/level2dir8/file1
. . .

This will produce a lot of results. If you pipe the output into a counter, you will see that there are a total of 1111 results:

find -name file1 | wc -l
Output
1111

This is probably too many results to be useful to you in most situations. To limit it, you can specify a maximum search depth in the top-level search list:

find -maxdepth num -name query

To find file1 only in level1 and higher directories, you can specify a maximum depth of 2 (1 for the top-level directory and 1 for level1 directories):

find -maxdepth 2 -name file1
Output
./level1dir7/file1
./level1dir1/file1
./level1dir3/file1
./level1dir8/file1
./level1dir6/file1
./file1
./level1dir2/file1
./level1dir9/file1
./level1dir4/file1
./level1dir5/file1
./level1dir10/file1

This is a very manageable list.

You can also specify a minimum directory if you know that all files from a certain point exist below the current directory:

find -mindepth num -name query

You can use this to find only files at the end of directory branches:

find -mindepth 4 -name file1
Output
./level1dir7/level2dir8/level3dir9/file1
./level1dir7/level2dir8/level3dir3/file1
./level1dir7/level2dir8/level3dir4/file1
./level1dir7/level2dir8/level3dir1/file1
./level1dir7/level2dir8/level3dir8/file1
./level1dir7/level2dir8/level3dir7/file1
./level1dir7/level2dir8/level3dir2/file1
. . .

Again, it returns a large number of results (1000) due to the branch-and-file structure.

You can combine the minimum and maximum depth parameters to focus on a narrow range:

find -mindepth 2 -maxdepth 3 -name file1
Output
./level1dir7/level2dir8/file1
./level1dir7/level2dir5/file1
./level1dir7/level2dir7/file1
./level1dir7/level2dir2/file1
./level1dir7/level2dir10/file1
./level1dir7/level2dir6/file1
./level1dir7/level2dir3/file1
./level1dir7/level2dir4/file1
./level1dir7/file1
. . .

Combining these options like this will significantly reduce the results, with only 110 lines returned instead of the previous 1000 lines.

Executing commands to find results

You can use the parameter -exec Run a custom helper command on anything that matches using the following command:

find find_parameters -exec command_and_options {} \;

{} is used as a placeholder for files that match. \; lets us know where the command ends.

For example, assuming you are still in the /test/ directory that you created in the previous step in the /tmp/ folder, you can find the files from the previous section that had 644 permissions and change them to have 664 permissions:

find . -type f -perm 644 -exec chmod 664 {} \;

You can also change directory permissions in a similar way:

find . -type d -perm 755 -exec chmod 700 {} \;

This example finds any directory with permissions set to 755 and then changes the permissions to 700.

Finding files using Locate

Alternative to using find Order locate This command is often faster and can search the entire file system easily.

You can install the command in Debian or Ubuntu with apt by updating your package list and then installing the molocate package:

sudo apt update
sudo apt install mlocate

On Rocky Linux, CentOS, and other RedHat-derived distributions, you can use the dnf command to install mlocate:

sudo dnf install mlocate

The reason locate is faster than find is that it relies on a database that lists all the files on the file system. This database is usually updated once a day with a cron script, but you can update it manually with the updatedb command. Now run this command with sudo privileges:

sudo updatedb

Remember, if you want to find new files, the location database must always be up to date. If you add new files before the cron script runs or before the updatedb command runs, they will not appear in the query results.

Location allows you to filter results in a variety of ways. The most basic way you can use to find files is to use this syntax:

locate query

This will match any file or directory that contains the string query anywhere in their file path. To return only files whose names contain the query itself, rather than any files that contain the query in the directories leading to it, you can add the -b flag to search only files whose "base name" matches the query:

locate -b query

To have the locate only return results that still exist on the file system (i.e. files that have not been deleted between the last updatedb call and the current locate call), use -e:

locate -e query

You can retrieve statistics about the information where the location is listed using the -S option:

locate -S
Output
Database /var/lib/mlocate/mlocate.db:
21015 directories
136787 files
7727763 bytes in file names
3264413 bytes used to store database

This can be useful for getting a high-level understanding of the number of files and directories on your system.

Result

Both find and locate are useful tools for finding files on your system. Both are powerful commands that can be enhanced by combining them with other tools via pipelines, but it is up to you to decide which tool is right for your situation. From here, we encourage you to continue experimenting with find and locate. You can read their respective man pages to learn about other options not covered in this guide, and you can analyze and manipulate the search results by feeding them into other commands such as wc, sort, and grep.

Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like