How to locate files and directories easily with Linux mlocate

Main picture of the post: How to locate files and directories easily with Linux mlocate

In this post it will describe the locate command, which is a great tool to search files and directories in the system. This command does not work alone and needs to be helped by another one called updatedb used to create and update a data base of the current existing files on the system.

Let’s start with the previous steps before using locate with the command updatedb to create the database.

Create or update the locate database

First of all, the locate database it’s placed by default in the path /var/lib/mlocate/mlocate.db and contains the data that locate will use to search the information that user is looking for.

$ sudo ls -l /var/lib/mlocate/mlocate.db
-rw-r-----. 1 root slocate 1253188 Apr 18 00:04 /var/lib/mlocate/mlocate.db

To create or update the locate database it’s simple, but needs root privileges to execute the command updatedb:

$ sudo updatedb

This will create the mlocate.db file if doesn’t exist or update it with any new information found in the system like new directories or files. So it is not a big issue if the file was removed accidentally since you can recreate it with the previous command whenever you want.

However, since the mlocate.db is not updated until you run the command updatedb, there could be some files or directories that would not appear with the locate command. So, in order to update any incremental data, the updatedb command is executed periodically with cron in a daily fashion:

$ sudo cat /etc/cron.daily/mlocate
#!/bin/sh
nodevs=$(awk '$1 == "nodev" && $2 != "rootfs" && $2 != "zfs" { print $2 }' < /proc/filesystems)

renice +19 -p $$ >/dev/null 2>&1
ionice -c2 -n7 -p $$ >/dev/null 2>&1
/usr/bin/updatedb -f "$nodevs"

Bear in mind this potential incremental data not being updated on the database and ensure to execute the updatedb previously using locate.

The locate command syntax

The syntax of the command is described as the following:

locate [OPTION]… [PATTERN]…

By default, the command will use the database located in the path /var/lib/mlocate/mlocate.db if it is not explicitly passed in the command arguments with the “-d” option.

Here you can find some of the command options which this post will explain in detail:

-A : only print entries that match all patterns

-c : only print number of found entries

d : Specify another DB path to use

-i : ignore case distinctions when matching patterns

-r : search for basic regexp REGEXP instead of patterns

The locate command allows to combine different options to obtain your desired results.

Search a particular file name or file extension in the whole system

Let’s begin with a very basic use case, where you want to find out a particular file in the system:

$ locate boot.log
/var/log/boot.log

In the example above, without the need to change directory, locate is able to find the file by using its database.

Moreover, locate search patterns by default so in the following examples, it will show how to find files with a particular extension or pattern:

$ locate messages
/usr/include/c++/4.8.2/x86_64-redhat-linux/32/bits/messages_members.h
/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/messages_members.h
/usr/share/vim/vim74/ftplugin/msmessages.vim
/usr/share/vim/vim74/syntax/messages.vim
/usr/share/vim/vim74/syntax/msmessages.vim
/usr/src/kernels/3.10.0-1160.49.1.el7.x86_64/include/config/compat/netlink/messages.h
/var/log/messages
$ locate .txt.gz
/usr/share/doc/sed-4.2.2/sedfaq.txt.gz
/usr/share/vim/vim74/doc/arabic.txt.gz
/usr/share/vim/vim74/doc/autocmd.txt.gz
/usr/share/vim/vim74/doc/change.txt.gz
/usr/share/vim/vim74/doc/cmdline.txt.gz
/usr/share/vim/vim74/doc/debug.txt.gz
/usr/share/vim/vim74/doc/debugger.txt.gz
...

Refine your locate search with multiple patterns

The command admits more than one pattern so, if no other options are specified, it will get all the files that match any of the patterns specified:

$ locate ".txt.gz" ".vim" | head
/usr/share/cmake/editors/vim/cmake-help.vim
/usr/share/cmake/editors/vim/cmake-indent.vim
/usr/share/cmake/editors/vim/cmake-syntax.vim
/usr/share/doc/sed-4.2.2/sedfaq.txt.gz
...

Nevertheless, it is possible to use the “-A” option to get the file paths that matches all the patterns stated in the command:

$ locate -A ".vim" "tutor" 
/usr/share/vim/vim74/tutor/tutor.vim

Print only the match count with locate

Instead of getting the file paths, you may want to get only the match count with the locate search by using the “-c” option:

$ locate -c "tutor" ".vim" 
1281

The count option can be combined with others like:

$ locate -c -A "tutor" ".vim" 
1

Run locate with ignore case

The option “-i” allows you to perform the search ignoring case and it can be combined with other options as well:

$ locate -A -i audit .h
/usr/include/linux/audit.h
/usr/include/linux/netfilter/xt_AUDIT.h
/usr/src/kernels/3.10.0-1160.49.1.el7.x86_64/include/asm-generic/audit_change_attr.h
/usr/src/kernels/3.10.0-1160.49.1.el7.x86_64/include/asm-generic/audit_dir_write.h
...
$ locate -A -i -c audit .h
19

The examples above are running locate with multiple patterns (“audit” and “.h”) with ignore case option and printing only the files that match all the patterns. In the other hand, the second command is getting only the match count.

Execute locate to use another database

If you have a database called “mydb.db” with the information updated like:

$ ls -ltr
total 1228
-rw-r-----. 1 root slocate 1256259 Apr 18 00:52 mydb.db

You might want to run the command and specify that particular database to obtain the search results:

$ locate -d mydb.db lastlog
/usr/bin/aulastlog
/usr/bin/lastlog
/usr/include/lastlog.h
/usr/lib64/security/pam_lastlog.so
/usr/share/doc/pam-1.1.8/html/sag-pam_lastlog.html
/usr/share/doc/pam-1.1.8/txts/README.pam_lastlog
/usr/share/man/man8/aulastlog.8.gz
/usr/share/man/man8/lastlog.8.gz
/usr/share/man/man8/pam_lastlog.8.gz
/var/log/lastlog

Use locate with regular expressions to increase the complexity of the searches

In the next example, locate, with “-r” options, is searching files that contains the regexp pattern “/” followed by any character, the string “last” and followed by another character:

$ locate -r "/.last."
/usr/lib/firewalld/services/elasticsearch.xml

Another example showed in the next section, the locate command is searching file paths starting with “/var/log/las”, followed by a lower case alphabet letter and ended by string “log”:

$ locate -r "^/var/log/las[a-z]log$"
/var/log/lastlog

Finally, another useful search pattern could be the next one:

$ locate -r "\.log$"
/usr/lib/rpm/rpm.log
/var/log/boot.log
/var/log/yum.log
/var/log/tuned/tuned.log

The previous command line will get the files ended with a dot symbol and followed by “log” or, in other words, all the files with extension “.log”.

Print database statistics

If you want to get details about the mlocate database, the “-S” option can be used to do so:

$ locate -S
Database /var/lib/mlocate/mlocate.db:
        7,693 directories
        55,186 files
        2,808,958 bytes in file names
        1,259,187 bytes used to store database

The “-S” option can be combined with “-d” to target a specific mlocate database.