Verified and Tested 2/22/16
Introduction
The Linux find command allows you to find files or directories using fields such as age, group, name, last modified, size, type, and many others. This is very useful when you’re working on a Linux system which you are not familiar with. We will go over the basic and most commonly used flags you’ll run into in our Find section.
The Linux locate command comes paired with its partner updatedb. The locate command allows you to locate files that contain your searching criteria and displays them out for you. The updatedb partner it has is what keeps the locate command up to date on the files in your system. It can essentially be seen as a directory list and your locate command helps you sort through for locations/files that have what your searching for in the path or name.
Prerequisites
A Linux server with find and locate installed. Try our Linux Cloud Hosting if you don’t have one – we even offer dedicated server hosting. The find command typically comes installed on Linux operating systems by default. If it does not, you can use your operating system’s package manager(yum, apt-get, pkg_add) to install it. Depending on your operating system, locate may be installed as well. If it is not, you can install it via your operating system’s package manager and installing its containing package. This package is typically called “mlocate.”
Let’s Find Something!
If at any time you are confused by find and it’s command or you wish to know even more about it, you can bring up its manual with the below command. The manual contains all information regarding using the find command in great detail.
# man find
When using find, you would follow the syntax below.
find [options] [path] [expression]
options: This is optional. You can leave this out most of the time. You can read the manual page for all the options the find command has.
path: This is the directory you want to search.
expression: This is where you place your search criteria for what you want to find whether by name, or size etc.
With the below we will be going over multiple ways on using find.
Let’s find any files named index.html without knowing the directories the files may be in.
#find / -name 'index.html' /usr/libexec/webmin/time/help/index.html /usr/libexec/webmin/fdisk/help/index.html /usr/libexec/webmin/inittab/help/index.html /usr/libexec/webmin/dfsadmin/help/index.html /usr/share/gtk-doc/html/liboil/index.html /usr/share/gtk-doc/html/schroedinger/index.html /usr/share/gtk-doc/html/pango/index.html /usr/share/gtk-doc/html/cairo/index.html /usr/share/gtk-doc/html/libxml2/index.html /usr/share/gtk-doc/html/atk/index.html
/ : This is the “/” directory which causes you to search the entire “slash” directory.
-name : This is the flag telling “find” to search for a pattern, in this case, the name pattern which compares the names of files with your expression.
‘index.html’ : This is the expression you’re searching for.
Now we’ll find a file call index.html in a specified directory.
#find /var/www/html -name 'index.html' /var/www/html/index.html
This will cause find to search only the /var/www/html directory for any files named ‘index.html’.
In this example, we’ll have “find” find a file call index.html in a specific directory ignoring the casing of the name.
#find /var/www/html -iname 'index.html' /var/www/html/INDEX.html /var/www/html/index.html
-iname : This is the flag telling “find” to search for an expression, while ignoring the case of the text.
Now we’ll search and “find” a directory’s name while ignoring the case of the directory.
#find / -type d -iname 'www' /usr/share/perl5/WWW /var/www /opt/ss/var/www
-type d : This tells find to look only for directories, not files. If you change the “d” to “f” you will get the opposite and find files instead.
And now we’ll find every file on the system that ends in .php.
# find / -type f -iname "*.php" /var/www/html/zm/views/file.php /usr/share/wordpress/wp-admin/ms-themes.php /usr/share/php/getid3/module.archive.szip.php /usr/share/doc/php-PHPMailer-5.2.2/examples/test_smtp_advanced_no_auth.php
*.php : The * in the expression stands for a wildcard. A wildcard will grab any file it finds as long as it ends with what follows it. In this case it is “.php”
We will continue with an example of finding a file ending with .cgi that has 755 permissions and we’ll ignore the case.
# find / -type f -iname "*.cgi" -perm 755 /usr/libexec/webmin/bacula-backup/backup_form.cgi /usr/libexec/webmin/bacula-backup/label_form.cgi /usr/libexec/webmin/bacula-backup/save_file.cgi /usr/libexec/webmin/bacula-backup/index.cgi /usr/libexec/webmin/bacula-backup/edit_pool.cgi /usr/libexec/webmin/bacula-backup/gbackup.cgi /usr/libexec/webmin/bacula-backup/edit_job.cgi
-perm 755 : The flag ‘-perm’ searches permissions in the directory specified. In our case it searches for files with ‘755’ permissions.
Now we’ll get time specific. We’ll search for files which have been modified between now and 10 days ago.
# find / -type f -mtime -10 (we don't have any)
-mtime -10 : Find any file that’s been modified between now and 10 days ago in the specified directory. As you can see the from 10 days ago til now is signified by the “-” in front of the 10. If you wanted to find anything older than 10 days, you can change the “-” to a “+”. This will have the search only list files that were changed 10 days ago and onward. If you wanted to find a file changed in the last 24 hours, you can actually use “-mtime 0” as it has not been a full 24 hours.
We can find files by size.
# find / -type f -size +50M -size -100M /usr/sbin/mysqld-debug /usr/sbin/mysqld /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.31-1.b13.el6_6.x86_64/jre/lib/rt.jar /usr/lib/locale/locale-archive /var/log/messages /var/lib/rpm/Packages
-size +50M -size -100M : With “-size” you tell find to search by size. In our case +50M which would be files more than 50 megabytes in size. We limit the search with a -100M which means the maximum file size can only be 100 megabytes. You can specify other file sizes such as bytes(c), kilobytes(k), and gigabytes(G). Case does count in this situation as not using the correct notation can lead you searching for the wrong information.
And finally, find can not only be used to search for files or directories, but you can also execute and run commands for each item found. Please note that executing a command while using find can lead to dangerous results if you do not know exactly what you are doing.
# find / -type f -size +50M -size -100M -exec du -lsh {} \; 70M /usr/sbin/mysqld-debug 84M /usr/sbin/mysqld 62M /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.31-1.b13.el6_6.x86_64/jre/lib/rt.jar 95M /usr/lib/locale/locale-archive 65M /var/log/messages 54M /var/lib/rpm/Packages
-exec : This flag tells find that for each item found, run the following command
du -lsh : This command prints in a more readily human readable format that size of a file.
{} : This serves as a placeholder. Each time an item is found, the item is placed in place of these brackets and executes the command preceding these brackets. So in the example find will execute a “du -lsh” on it item found.
\; : This finishes the “-exec” statement. You must end every find command containing “-exec” with a ‘\;’ or it will fail.
And that’s the basics of using the Linux command “find”. There are many more flags to explore such as “printf” for output formatting, “max/min depth” which limit how deep find will dive into a directory, and “newer” which compares if a file was modified more recently than another file. Keep using find and soon you’ll be able to “find” anything.
Let’s Locate Some Files!
Locate in a few ways is like “find” discussed above in that it is another method of searching your operating system to find a file. One of the key differences with locate is that it will discern between a directory or file. It will always look for both. Locate comes paired with it’s partner command “updatedb” which, as it looks like, updates the DB or database of files it has that locate can parse through. Locate will not provide you with full, accurate results unless you run it’s partner, “updatedb” first.
When using locate, you’d want to follow the syntax below.
locate [OPTION] PATTERN
[OPTION] : Would be any and all options that locate can use. For a full list of the options, you can see the manual page (#man locate).
PATTERN : This is what you would be searching for.
So getting started, lets first run updatedb.
#updatedb
Updatedb will not give any output but will simply drop the shell to the next line once it has completed. Now lets try to locate any .repo file.
# locate *.repo /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Debuginfo.repo /etc/yum.repos.d/CentOS-Media.repo /etc/yum.repos.d/CentOS-Vault.repo /etc/yum.repos.d/CentOS-fasttrack.repo
*.repo : This again is a wildcard search which allows us to find any and all files that end in .repo
You can use locate to find directories as well. In this case, we only want to look for the www directory, so we restrain the search to looking only for “www”.
# locate -b www /usr/share/groff/1.18.1.4/tmac/www.tmac /usr/share/man/man7/groff_www.7.gz /var/www
-b : This option tells locate only to pull files/directories that contain or end with www and nothing else. The opposite of this is -w which is what locate does by default and will find absolutely anything with your pattern in it.
We can also tell locate to search for a file or directory and ignore any casing.
# locate -bi noindex.html /var/www/error/NOINDEX.html /var/www/error/noindex.html
-bi : The -b option is explained above but this time we tacked on -i as well. -i is what allows you to ignore casing in your search.
Now lets say you want to limit your locate results to only a few. We’ll use the *.repo search early and search for only three results.
# locate -il 3 *.repo /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Debuginfo.repo /etc/yum.repos.d/CentOS-Media.repo
-il 3 : The new tack on this time is -l #. -l tells locate to limit the search to the number of results you put after it. If you use -l, remember to always use it last on your options list if you are combining options or to separate it (in this case -i -l 3) otherwise you will get an error.
Unfortunately locate does not have a built-in ability to execute commands per result found like find does. But like “find” and most any commands in Linux, you can pipe the results to narrow out your results. “find” allows you to do a lot of limiting with the options it provides but locate doesn’t have that innate ability. So to limit our results we’ll “pipe” them to “grep” which is a command that prints lines only for the results containing the pattern given to it.
# locate -i index.html | grep www /var/www/error/NOINDEX.html /var/www/error/noindex.html
| : This is the pipe command
grep www : This limits out the results to only list the results that have a www in them whether in the name or part of the directory.
And those are the basics of the locate command. While it doesn’t have the flexibility that the find command may have, it is another searching tool and doesn’t require you to know much about Linux to use it. There are options to provide more results like -L which will follow symbolic links, -e which only lists files that exist at the time locate is run, and -c which provides a count for how many results are found, and more. The very best thing to remember about using locate is to always make sure that you do an updated before running locate to get accurate, up-to-date results.