Linux find examples

The Linux find command is a very helpful and frequently used command. It is used to locate files and directories. It allows you to specify a host of options that can help you locate what file or directory you may be looking for. The output of find can be used as input for other commands or operations.

I use the find command extensively and I am always looking for examples of how to use the find command.

In this post, I am going to list Linux find examples that I often use or need to know. I will also list some examples where the output of the find command is used to do some other task.

find examples


find   # search from present working directory
.
./masterfile
./Masterfile
./A
./A/B
./a
./a/128k-aaab
./a/b                                                                                                                                                                                                                                                              ./a/128k-aaad                                                                                                                          ./a/128k-aaaa                                                                                                                          ./a/128k-aaac
          

Just typing find without any options will search for file and directories from your present working directory.

You can also specify a starting point or multiple starting points as shown below


find /home/bitnami
find /var/cache /usr/local/bin

if you do not have permission to access a directory you will see a message in your output.


var/cache/apt/archives/partial
find: ‘/var/cache/apt/archives/partial’: Permission denied
/var/cache/apt/archives/lock

If you only wanted to search for files or directories you can use the option -type to refine your search.


find . -type f        # files
./masterfile
./Masterfile
./A/128K-aaac
./A/128K-aaad
./A/128K-aaaa
./A/128K-aaab                                                                                                                          ./a/128k-aaab                                                                                                                          ./a/128k-aaad                                                                                                                          ./a/128k-aaaa                                                                                                                          ./a/128k-aaac    

find . -type d        # directories
.                                                                                                                                      ./A                                                                                                                                    ./A/B                                                                                                                                  ./a                                                                                                                                    ./a/b
                                                  

find based on file or directory name

You can refine your search by specifying a name and if needed make it case insensitive. You can specify multiple names or use a wildcard.

find -name masterfile                                                                           ./masterfile   

find . \( -name  masterfile -o -name Masterfile \)
./masterfile
./Masterfile

find -iname masterfile                                                                          ./masterfile                                                                                                                           ./Masterfile 

find  . -type f -name "*a"
./A/128K-aaaa
./a/128k-aaaa

                                                  

Adding the -ls option lists the output in ls -dils format on standard output.


find . -type d -ls
  1024311      4 drwxr-xr-x   4 bitnami  bitnami      4096 Aug 10 17:10 .                                                                
  1031022      4 drwxrwx---   3 bitnami  bitnami      4096 Aug 10 17:08 ./A                                                              
  1031025      4 drwxrwx---   2 bitnami  bitnami      4096 Aug 10 17:03 ./A/B                                                            
  1024590      4 drwxr-xr-x   3 bitnami  bitnami      4096 Aug 10 17:05 ./a                                                              
  1031023      4 drwxr-xr-x   2 bitnami  bitnami      4096 Aug 10 17:09 ./a/b  

maxdepth

find is a recursive command, it will scan all directories from the search path. You can however limit how deep you want find to traverse the directory path.


find . -maxdepth 1 -type f # maxdepth 0 is the starting directory only
./masterfile
./sbali
./Masterfile

#compare

find . -maxdepth 2 -type f
./masterfile
./sbali
./Masterfile
./A/128K-aaac
./A/128K-aaad
./A/128K-aaaa
./A/128K-aaab
./a/128k-aaab
./a/128k-aaad
./a/128k-aaaa
./a/128k-aaac

Note: -maxdepth should be the first option listed in the find command i.e. maxdepth 1 should be before type or size or other option used.

find based on file or directory permissions

Add the -perm option to look for files or directories based on their permissions.


find . -type d -ls -perm 0770
  1024311      4 drwxr-xr-x   4 bitnami  bitnami      4096 Aug 10 17:10 .                                                                
  1031022      4 drwxrwx---   3 bitnami  bitnami      4096 Aug 10 17:08 ./A                                                              
  1031025      4 drwxrwx---   2 bitnami  bitnami      4096 Aug 10 17:03 ./A/B                                                            
  1024590      4 drwxr-xr-x   3 bitnami  bitnami      4096 Aug 10 17:05 ./a                                                              
  1031023      4 drwxr-xr-x   2 bitnami  bitnami      4096 Aug 10 17:09 ./a/b

find based on file or directory uid, gid, user or group

You can search by uid, gid, user or group or a combination of these.


find . -uid 0 -ls
  1026174    400 -rw-r--r--   1 root     root       409600 Aug 10 17:07 ./masterfile

find . -gid 0 -ls
  1026174    400 -rw-r--r--   1 root     root       409600 Aug 10 17:07 ./masterfile

find . -user root -ls
  1026174    400 -rw-r--r--   1 root     root       409600 Aug 10 17:07 ./masterfile

find . -group root -ls
  1026174    400 -rw-r--r--   1 root     root       409600 Aug 10 17:07 ./masterfile

find based on size

find allows you to search based on size. Here are some examples


find . -type f -size -32k -ls  # Less than 32k
  1031038     16 -rwxrwx---   1 bitnami  bitnami     16384 Aug 10 17:08 ./A/128K-aaad
  1031032     16 -rw-r--r--   1 bitnami  bitnami     16384 Aug 10 17:05 ./a/128k-aaad

find . -type f -size +399 -ls # more than 399 512 byte blocks
  1026174    400 -rw-r--r--   1 root     root       409600 Aug 10 17:07 ./masterfile
  1028148    400 -rw-r--r--   1 bitnami  bitnami    409600 Aug 10 17:10 ./Masterfile

You can also search for 0 byte file. In this example, I created an empty file and then used the size command to locate it.


touch sbali && find . -type f -size 0 -ls
  1024108      0 -rw-r--r--   1 bitnami  bitnami         0 Aug 10 17:39 ./sbali

Combine options to refine your output


find . -type f \( -size 0 -o -size +300k \) -ls
  1026174    400 -rw-r--r--   1 root     root       409600 Aug 10 17:07 ./masterfile
  1024108      0 -rw-r--r--   1 bitnami  bitnami         0 Aug 10 17:39 ./sbali
  1028148    400 -rw-r--r--   1 bitnami  bitnami    409600 Aug 10 17:10 ./Masterfile

find  . -type f -size +300k -name "[a-z]*"
./masterfile

find based on access, creation or modification time

You can search based on:

  • -amin n # File was last access n minutes ago.
  • -atime n # File was access n*24 hours ago. -atime +1, implies at least two days ago.
  • -cmin n # File status was changed n minutes ago.
  • -ctime n # File status was changed n*24 hours ago.
  • -mmin n # File data was last modified n minutes ago.
  • -mtime n # File data was last modified n*24 hours ago.

Note: Your file system should have “atime” enabled for access time


find . -type f -atime 0
./masterfile
./sbali
./Masterfile
./A/128K-aaac
./A/128K-aaad
./A/128K-aaaa
./A/128K-aaab
./a/128k-aaab
./a/128k-aaad
./a/128k-aaaa
./a/128k-aaac

Combining find and other commands

Count the number of files found


find . -type f | wc -l
11

Print filenames sorted by size from small to largest


find . -type f -ls | sort -k 7 -n  | awk ' { print $NF } '
./sbali
./a/128k-aaad
./A/128K-aaad
./a/128k-aaaa
./a/128k-aaab
./a/128k-aaac
./A/128K-aaaa
./A/128K-aaab
./A/128K-aaac
./masterfile
./Masterfile

find and delete files

This command is destructive. If any files match the criteria, it will delete them. Do not run this command unless you know what you are doing or you have a backup.


find <some_path> -type f -size 0 | xargs /bin/rm -f
find <some_path> -type f -size 0 -exec /bin/rm -f {} \;

The difference between -exec and xargs is that if you had a large number of files the rm would run against all of them one by one. In the case of xargs the input is grouped and the rm runs against them.

If you had a 1000 files to delete, -exec would run rm 1000 times vs xargs which will be much less.

If the command you are going to run does not accept more than one argument, then -exec would be the way to go.

Conclusion

I have only covered a few examples here that I end up using most of the times. I will keep adding more variations. Let me know if you need help with a particular option that I have not covered here and I will try to do my best.

Further Reading

Photo Credit

unsplash-logoAgence Olloweb

Leave a Reply