Blog
Learning Find - Searching for files and dirs on Linux/Mac

Sometimes you have to find files and folders on a computer. When you are working on a terminal in a remote system then there is no Apple Spotlight to help you search through your servers. Fortunately both Linux and Mac come with a command-line tool called ‘find’ that helps us find files and directories. It can even operate on files and directories in bulk. Lets learn some ‘find’ today!
Example Directory
I have prepared an example directory try out some of the search features of find. Just clone the repo and start a terminal session in the directory.
Find
The find command searches a given directory (and its subdirectories) for files based on a variety of attributes. When we type man find we read the following:
NAME
find -- walk a file hierarchy
SYNOPSIS
find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]
content
The find utility recursively descends the directory tree for each path listed, evaluating an expression (composed of the ``primaries'' and ``operands'' listed below) in terms of each file in the tree.
Find all files an directories
To search for all files and directories type:
$ find .
.
./LICENSE
./bin
./bin/hello.sh
./bin/bye.sh
./web
...
Find files only
To search for files only type:
$ find . -type f
./LICENSE
./bin/hello.sh
./bin/bye.sh
./web/index.html
...
Find directories only
To search for directories only type:
$ find . -type d
.
./bin
./web
./web/img
./java
./test-dir
./.git
...
Find a file with a specific name
To search for a file with a name type:
$ find . -type f -name "test1.txt"
./test-dir/test1.txt
Use a wildcard * to widen the search:
$ find . -type f -name "test*.txt"
./test-dir/test7.txt
./test-dir/test6.txt
./test-dir/test4.txt
./test-dir/test5.txt
./test-dir/test1.txt
./test-dir/test2.txt
./test-dir/test3.txt
./test-dir/test10.txt
./test-dir/test8.txt
./test-dir/test9.txt
Find files case insensitive
To search for files case insensitive type:
$ find . -type f -iname "test*.txt"
./test-dir/test7.txt
./test-dir/test6.txt
./test-dir/test4.txt
./test-dir/test5.txt
./test-dir/test1.txt
./test-dir/test2.txt
./test-dir/test3.txt
./test-dir/TEST_8.txt
./test-dir/TEST_9.txt
./test-dir/TEST_10.txt
./test-dir/test10.txt
./test-dir/TEST_2.txt
./test-dir/TEST_3.txt
./test-dir/TEST_1.txt
./test-dir/TEST_4.txt
./test-dir/TEST_5.txt
...
To search for Python files type:
$ find . -type f -iname "*.py"
./test-dir/test.py
To search for all image files type:
$ find . -type f -iname "*.jpg"
./michael-sum-565770-unsplash.jpg
./jonas-vincent-2717-unsplash.jpg
./web/img/michael-sum-565770-unsplash.jpg
./web/img/jonas-vincent-2717-unsplash.jpg
./web/img/raul-varzar-750436-unsplash.jpg
./web/img/jari-hytonen-538885-unsplash.jpg
./web/img/karina-vorozheeva-666313-unsplash.jpg
./web/img/nathalie-jolie-681356-unsplash.jpg
./web/img/eric-han-455080-unsplash.jpg
./web/img/mikhail-vasilyev-253977-unsplash.jpg
./raul-varzar-750436-unsplash.jpg
./jari-hytonen-538885-unsplash.jpg
./karina-vorozheeva-666313-unsplash.jpg
./nathalie-jolie-681356-unsplash.jpg
./eric-han-455080-unsplash.jpg
./mikhail-vasilyev-253977-unsplash.jpg
Find files base on time
To search for files, we can use the mmin, amin, cmin, mtime, atime or ctime. The ‘cma’ means created, modified or accessed. The min means minutes and time means days. To search for files that are created less than 10 minutes ago, type:
$ find . -type f -ctime -10
./LICENSE
./bin/hello.sh
./bin/bye.sh
./web/index.html
./web/readme.md
...
To search for files that were modified more than 10 days ago, type:
$ find . -type f -mtime +10
Find files on file size
To search for files over 5 megabytes type:
$ find . -size +5M
./web/img/jari-hytonen-538885-unsplash.jpg
./.git/objects/f2/d996ce562ad4203c33331f52824fb0e54d050f
To search for files less than 1MB type:
find . -size -1MB
.
./LICENSE
./bin
./bin/hello.sh
./bin/bye.sh
...
To search for empty files type:
$ find . -type f -empty
./bin/hello.sh
./bin/bye.sh
./web/readme.md
./java/readme.md
./test-dir/test7.txt
./test-dir/test6.txt
...
Search for access permissions
To search for files based on access permissions type:
$ find . -perm 777
./web/index.html
./web/readme.md
./web/img
./web/img/michael-sum-565770-unsplash.jpg
./web/img/jonas-vincent-2717-unsplash.jpg
./web/img/raul-varzar-750436-unsplash.jpg
./web/img/jari-hytonen-538885-unsplash.jpg
./web/img/karina-vorozheeva-666313-unsplash.jpg
./web/img/nathalie-jolie-681356-unsplash.jpg
./web/img/eric-han-455080-unsplash.jpg
./web/img/mikhail-vasilyev-253977-unsplash.jpg
Executing commands on result
we can execute a command in batch on the search result. Note the {} + part. We have to type that.
find . -size +5M -exec ls -alh {} +
-r--r--r-- 1 dennis staff 8.8M Nov 19 04:41 ./.git/objects/f2/d996ce562ad4203c33331f52824fb0e54d050f
-rwxrwxrwx@ 1 dennis staff 8.9M Nov 19 04:33 ./web/img/jari-hytonen-538885-unsplash.jpg
Lets do something about those files that have ‘777’ permissions. Lets change that to ‘664’:
$ find . -type f -perm 777 -exec chmod 664 {} +
$ find . -type f -perm 664
./web/index.html
./web/readme.md
./web/img/michael-sum-565770-unsplash.jpg
./web/img/jonas-vincent-2717-unsplash.jpg
./web/img/raul-varzar-750436-unsplash.jpg
./web/img/jari-hytonen-538885-unsplash.jpg
./web/img/karina-vorozheeva-666313-unsplash.jpg
./web/img/nathalie-jolie-681356-unsplash.jpg
./web/img/eric-han-455080-unsplash.jpg
./web/img/mikhail-vasilyev-253977-unsplash.jpg
Lets change the directory with ‘777’ permission to ‘775’:
$ find . -type d -perm 777
./web/img
$ find . -type d -perm 777 -exec chmod 775 {} +
$ find . -type d -perm 775
./web/img
Depth of search
To find for files only in the current directory use the ‘maxdepth’ option:
$ find . -type f -iname "*.jpg" -maxdepth 1
./michael-sum-565770-unsplash.jpg
./jonas-vincent-2717-unsplash.jpg
./raul-varzar-750436-unsplash.jpg
./jari-hytonen-538885-unsplash.jpg
./karina-vorozheeva-666313-unsplash.jpg
./nathalie-jolie-681356-unsplash.jpg
./eric-han-455080-unsplash.jpg
./mikhail-vasilyev-253977-unsplash.jpg
Lets remove those files:
$ find . -type f -iname "*.jpg" -maxdepth 1 -exec rm {} +
$ find . -type f -iname "*.jpg" -maxdepth 1
<empty>
Conclusion
Find is available on both Linux and Mac. My knowing a few options you can effectively search for directories and files. Find also allows to operate on the search result with the ‘exec’ option. When used effectively, find can save you a lot of time doing file operations.