Skip to main content

File Searching Commands

find Command Examples

Learn the super powerful and super useful find command with these practical examples.

The find command is used for searching for files and directories in the Linux command line.

Find is one of the most powerful and frequently used commands. It is also one of the most extensive commands with over 50 options and this makes it a bit confusing, specially when it is paired with the exec or xargs command.

It is impossible for a sysadmin or software developer to avoid the find command while working in the command line. Instead of being afraid of it, you should embrace its power.

I am going to discuss some of the most common examples of the find command that you are likely to use. But before that, let me show you its syntax and how to use it.

Find command syntax

The general syntax for the find command is:

find [directory to search] [options] [expression]

Everything in brackets [] are optional. It means that you can run find command without any options and arguments. It will just dump all the files and directories in the current location. That's not very useful, right?

Let's look at it in more detail:

  • directory to search is basically the location from where you want to start your search. By default, the search is recursive and starts from your current location.
  • options specify the type of search, be it by name, by type, by modified time etc. There are more than 50 options possible here.
  • expression allows you to specify the search term. If you want to find a file by its name, expression is the file name. If you want to find files with name matching a pattern, expression in the pattern.

Let me take a simple example:

find . -type f -name myfile

This command will run a search in the current directory and its subdirectories to find a file (not directory) named myfile. The option -type f asks it to look for files only. The single dot . means the current directory.

Let's see some practical examples of the find command.

Find files and directories by name

You can search for files and directories by its name:

find . -name SEARCH_NAME

Since there is no file type mentioned, it searches for both files and directories with the given name.

The below example finds both file and directories named mystuff:

abhishek@LHB:~/Examples$ find -name mystuff
./new/mystuff
./mystuff
Find Files by Name in Linux [5 Frequent Use Cases]
Finding files by their name is one of the most common scenarios of finding files in Linux. Here are a few examples to help.

Find only files or only directories

If you only want to look for files, specify file type -f:

find . -type f -name SEARCH_NAME

The order of type and name does not matter. Take the previous example and find for files only:

abhishek@LHB:~/Examples$ find -type f -name mystuff
./mystuff

If you only want to search for directories, specify type -d:

find . -type d -name SEARCH_NAME

In the previous file, look for directories only:

abhishek@LHB:~/Examples$ find -type d -name mystuff
./new/mystuff

By default, the find command is case sensitive. You can run a case-insensitive search with the given name by using -iname instead of -name.

find . -type f -iname SEARCH_NAME

You can use it with type d as well.

abhishek@LHB:~/Examples$ find -iname mystuff
./new/mystuff
./MyStuff
./mystuff

Screenshot of the above three examples:

Search files by their extension (important)

One of the most common use of the find command is to find files of a specific type or should I say a specific extension.

For example, let's say, you want to search for all the C++ files in the current directories. The C++ files end with extension .cpp, so you can search it like this:

find . -type f -name "*.cpp"

This way, you tell the find command to look for type file and with names that end with .cpp.

abhishek@LHB:~$ find . -type f -name "*.cpp"
./file.cpp
./.cargo/registry/src/github.com-1ecc6299db9ec823/libz-sys-1.1.3/src/zlib/contrib/iostream2/zstream_test.cpp
./.cargo/registry/src/github.com-1ecc6299db9ec823/libz-sys-1.1.3/src/zlib/contrib/iostream/test.cpp
./.cargo/registry/src/github.com-1ecc6299db9ec823/libz-sys-1.1.3/src/zlib/contrib/iostream/zfstream.cpp
💡
Always put your search expression in double quotes when using the find command.

Why do I recommend using double quotes or single quotes around your search term? Because if you do not do that, the shell will expand the wildcard.

If you do not wrap your search term in quotes:

find . -type f -name *.cpp

Your shell will expand *.cpp and replace it with all the files in the current directory whose names end with .cpp.

This could work if there is only one file but if there are more than one, your shell will complain of incorrect syntax.

In the above example, there is only one cpp file and hence when the command expands to find . -type f -name file.cpp, it works because it file.cpp still works as search term.

But there are two .txt files in the same directory and hence when the command expands to find . -type f -name another.txt new.txt, it complains because there is more than one search term now.

This is why you should always wrap your search term in double quotes.

Search for multiple files with multiple extensions (or condition)

The above command searched for files with a given extension. What if you want to look for files with different extensions?

Instead of running the find command multiple times, run it once by using the -o option that works as logical OR condition:

find . -type f -name "*.cpp" -o -name "*.txt" 

Here's an example:

abhishek@LHB:~/Examples$ find . -type f -name "*.txt" -o -name "*.cpp"
./new.txt
./file.cpp
./new/new.txt
./new/dir2/another.txt
./new/dir1/new.txt
./another.txt

Look for files in a specific directory

So far, all the examples performed search in the current directory because you specified . in the examples.

The dot can be replaced with an absolute or relative path of a directory so that you can look for files in the specified directory without leaving your current location.

abhishek@LHB:~/Examples$ find ./new -name mystuff 
./new/mystuff

Search for files in multiple directories

If you think your desired file(s) could be located in several locations, you don't have to run find command multiple times. Just specify all the directory paths to search in the find command:

find ./location1 /second/location -type f -name "pattern"

Find empty files and directories

The -empty option enables you to look for empty files and directories with the find command.

To find all the empty files and directories in the current directory, use:

find . -empty

You can specify the file type to look only for empty files or directories:

find . -empty -type f

You may also combine it with the filename search:

find . -empty -type f -name "*.cpp"

Find big files or small (Search based on file size)

You can find big files or small files based on the search performed by the size parameter. This only works with files, not directories.

You use the -size option with +N for size greater than N and -N for size smaller than N.

Find files of exactly 50 KB in size:

find . -size 50k

To search for files bigger than 1 GB in the current directory:

find . -size +1G

To find smaller than 20 bytes:

find . -size -20c

To find files bigger than 100 MB but smaller than 2 GB in size:

find . -size +100M -size -2G

You may also combine the size search with the name search. For example, to search for all files with name ending in .log but size greater than 500 MB in the root directory, you can use:

find / -size +500M -name "*.log"

To recall:

  • c : bytes
  • k: kilobytes
  • M: Megabytes
  • G: Gigabytes

Find recently modified files (Search based on modify or creation time)

You know the concept of mtime, atime and ctime, right?

  • mtime: last modification time of file
  • ctime: creation time of the file
  • atime: last access time of the file

You'll often find yourself in situations where you want to find all the recently modified files. The search by modified time helps in such cases.

To find all the files modified within 3 days (3*24H), use:

find . -type f -mtime -3

To find all the files created at least 5 days (5*24H) ago, use:

find . -type f -ctime +5

I know 24 hours is a huge time frame. What if you want to search for files that were modified only a few minutes ago? For that, you can use mmin, amin and cmin.

To find all the files that were modified in the last 5 minutes, use:

find . -type f -mmin -5

You can specify upper and lower limits along with the search name. The command below will search for all the .java files that have been modified between last 20 to 30 minutes.

find . -type f -mmin +20 -mmin -30 -name "*.java"

Find files with specific file permissions

I hope you are familiar with the file permission concept in Linux.

The find command allows you to search for files with specific file permission and access mode.

find -perm mode

For example, to find all the files access mode 777 in the current directory;

find . -perm 777

To find all files with access of read and write for all (exact match, it won't match if the file has execute permission for all):

find . -perm a=r+w

Find files owned by a user

You can also search for files based on ownership.

For example, to find files owned by the user John in the current directory, use:

find . -type f -user John

You can also combine it with other options like size, time and name:

find . -type f -user John -name "*.cpp"

Don't find recursively, search only in current directory

By default, the find command searches recursively in all the subdirectories of your current location. If you don't want that, you can specify the depth of your search to 1. This will restrict the search to only the current directory and excludes any subdirectories.

find . -maxdepth 1 -type f -name "*.txt"

if you want to exclude a directory from the search, you can do that by combining path, prune and logical or.

find . -path "./directory_exclude/*" -prune -o -name SEARCH_NAME

Be careful with the * in the path of the directory, -prune after path and -o after prune.

Basically, the prune command asks to not use the value specified by path. Prune is always used with -o to ensure that right side of the terms are evaluated only for directories that were not pruned.

Take action on the result of find commands (exec and xargs)

So far, you have learned various ways to find files based on various criteria. That's good. But you can make it better by taking certain actions on the result of the find command.

For example, how about finding files matching certain name pattern and renaming them all at once or finding empty files and deleting them?

You know that pipe redirection can be used to combine the output of one command with the input of another command. But this won't work with the output of find command, at least not directly.

You have two options if you want to take an action on the result of find command:

  • Use exec
  • Use xargs

Using find and exec

Suppose you want to long list (ls -l) the search files with the find command. Here's what you use:

find . -type f -name "*.txt" -exec ls -l {} +

Here's the output:

abhishek@LHB:~/Examples$ find . -type f -name "*.txt" -exec ls -l {} +
-rw-rw-r-- 1 abhishek abhishek 39 Oct 13 19:30 ./another.txt
-rw-rw-r-- 1 abhishek abhishek 35 Oct 13 15:36 ./new/dir1/new.txt
-rw-rw-r-- 1 abhishek abhishek 35 Oct 13 15:36 ./new/dir2/another.txt
-rw-rw-r-- 1 abhishek abhishek 35 Oct 13 18:51 ./new/mystuff/new.txt
-rwxrwxrwx 1 abhishek abhishek 35 Oct 13 15:37 ./new/new.txt
-rw-rw-r-- 1 abhishek abhishek 35 Oct 13 18:16 ./new.txt

Many people forget to add the {} + at the end of the exec command. You must use it and mind the space between {} and +.

The {} is what references the result of the find command. You can imagine it to be like {file 1, file 2, file 3}. The + sign is used to terminate the exec command.

There is also another convention with exec:

find . -type f -name *.txt" -exec ls -l {} \;

Here, ; is used instead of the + sign. The additional \ before ; is used to escape the special character ;.

The advantage of {} + is that it runs fewer commands as ls -l file1 file2 file3 whereas {} \; will run ls -l file1, ls -l file2 etc.

But, {} \; has the advantage of using {} more than once in the same exec statement. For example, the command below will rename all the found files with .old extension.

find . -type f -name *.txt" -exec mv {} {}.old \;
Find Exec Command in Linux: 9 Useful Examples
Find works on searching files based on a number of criteria. The exec command gives you the ability to work on those results. Here are some examples of find exec command combination.

Using xargs

Many Linux users get used to of the pipe redirection. This exec command with the trailing {} + seems intimidating to them.

This is where xargs helps. You just parse the output of the find command to the xargs command via pipe.

find . -type f -name *.txt" | xargs ls -l

The syntax seems a lot simpler, right? Xargs command is also very powerful. You may read about it here.

How to Use Xargs Command in Linux [Explained With Examples]
xargs is one of the most powerful commands in Linux. In this tutorial, you’ll learn to use xargs command with some practical and useful examples.

Combining find and grep

Now that you know about combining find with exec and xargs command, you can use it to combine find and grep.

For any sysadmin or software developer, find and grep is one of the most common and yet most useful combination.

You search for file name patters with find and then use grep to search for the content inside those files.

For example, you want to search for all the .txt files that contain the term Alice. You combine find and grep like this:

find . -type f -name "*.txt" -exec grep -i alice {} +

The same can be achieved with xargs as well:

find . -type f -name "*.txt" | xargs grep -i alice

Of course, this is the simplest of the examples but if you are familiar with the grep command, you can use it to your liking and need.

💡 Bonus Tip: Avoid seeing 'permission denied' errors

When you run the find command on the root directory, you'll see a lot of 'permission denied' error in the output. That's because you don't have the rights to enter many directories owned by the root user.

So, what can you do? You can use sudo or you can redirect the errors to /dev/null and this way, you won't see those errors on the screen.

 find / -type f -name skypeforlinux.png 2>/dev/null

The errors will still be encountered, they just won't be displayed as you redirected them to /dev/null instead of stdout.

There is a lot more with find ...

And it is not possible to list all the find command options and examples. The possibilities are endless but when you get familiar with the find command, you can start using it in a variety of situations. That is really up to you how you combine the logic here.

I hope you find these examples of find command useful. If you still have questions or suggestions to improve this article, please let me know in the comment section.

Abhishek Prakash