Looking for a specific file in your Ubuntu system?
There are several commands for finding files in the terminal. The commands work well in different scenarios.
- find: when you know where to search
- locate: when you don't know where to search
- fd: find command, but multi-threaded and thus faster
The find command is perhaps the most popular and most reliable among the three. You can use it in its simplest form:
find LOCATION -name FILE_NAME
Replace 'LOCATION' with a directory in which you wish to search. The 'FILE_NAME' parameter can be replaced by the exact name of a file or by a regex.
For example, if I want to search for a file that is named 'resolution-for-year-2022.txt', only in my home directory, I would issue the following command:
find ~ -name resolution-for-year-2022.txt
There is more to the
find command, so keep reading if you want to know more!
The find command is an amazing command line utility that searches for a given filename/regex pattern in a specified directory.
You can provide multiple options to the find command, so let us look at them.
-name: Specify a case-sensitive filename/regex for the file to search for
-iname: Same as
-name, but case insensitive
-amin n: File was last accessed
nnumber of minutes ago
-mmin n: File was last modified
nnumber of minutes ago
-type: The type of a file. Use
lfor a directory, file and a symbolic link, respectively.
-empty: An empty file or a directory
-size n: File of size
Gfor specifying units in bytes, kibibytes, mebibytes and gibibytes, respectively.
-readable: Only files that the current user can read
-writable: Only files that the current user can write to
That is quite a list of available options. But, it does not even cover all the available options for the find command!
For better understanding, let us look at a few common examples of the find command.
Finding a file in a specific directory
Let us assume I have a photo named 'headshot.png' located somewhere in my home directory.
To find the photo, I would modify the find command's parameters as follows:
find ~ -name headshot.png
Here's the output:
$ find ~ -name headshot.png /home/pratham/Pictures/self/headshot.png
Ah! It was in the
You may also substitute the tilde symbol (
~) (for home directory) with the period symbol (
.) to search only in the current working directory.
Finding empty files
I made a mistake in my bash script, and now it has created empty files all over my home directory.
To find those empty files, I will use the
-empty flag and specify the type to be a file.
Note that the
-iname) option is not compulsory.
find ~ -type f -empty
Here's its output.
$ find ~ -type f -empty /home/pratham/Downloads/mt_file_1ybi /home/pratham/Pictures/you_can-t_see_me /home/pratham/.config/nvim/mt_file_wun2 /home/pratham/Documents/work/learn-ubuntu/mt_file_2qxur
As you can see, the find command listed all matching results. This can be confirmed that they are empty using the
$ du -sh ~/Downloads/mt_file_1ybi ~/Pictures/you_can-t_see_me ~/.config/nvim/mt_file_wun2 ~/Documents/work/learn-ubuntu/mt_file_2qxur 0 /home/pratham/Downloads/mt_file_1ybi 0 /home/pratham/Pictures/you_can-t_see_me 0 /home/pratham/.config/nvim/mt_file_wun2 0 /home/pratham/Documents/work/learn-ubuntu/mt_file_2qxur
Finding files with a particular extension
-iname options accept regular expression strings as inputs. That makes searching even more powerful.
Let us assume I wish to find all the
png files. I will do so with the following command:
$ find . -name "*.png" ./Pictures/dlsr/shot-2002-03-01.png ./Pictures/dlsr/shot-2022-03-01.png ./Pictures/pic-004.png ./Pictures/pic-001.png ./Pictures/pic-002.png ./Pictures/pic-003.png
Easy regex and a quick find!
Finding files with locate command
The locate command is one of the handiest commands when you do not remember the location of a file.
Sometimes, when following a tutorial for "Installing and configuring XYZ on CentOS" will show a different location for the config files. In cases like this, the locate command will surely come in handy when you do not know where a file is.
The locate command can be installed by running the following apt command in your terminal:
sudo apt install locate
The locate command depends on a frequently updated database of your filesystem. You must generate a database before the initial use of the locate command.
A database is created and updated using the
updatedb command, like so:
When the files are constantly being created, modified, moved and moved, the database must also be updated.
Since it gets tiresome manually generating the file database, you can create a cron job for root user to update the database hourly. To edit the cron file for root, use the
sudo crontab -e command. Then, add the following lines to the text file that opened.
0 * * * * updatedb
0 * * * * means to run the
updatedb command every hour, every day.
Once a database is generated, use the
locate command by providing only a filename. The syntax is given below:
Let us assume I wish to know the location of the
50-cloud-init.yaml file on my filesystem. To do so, I will execute the following command:
$ locate 50-cloud-init.yaml /etc/netplan/50-cloud-init.yaml
As expected, I got the result. The desired file is in the
The two main advantages of using the
locate command over using
find command are as follows:
locatecommand is incredibly fast compared to the
- Specifying a directory to search in is required with
findcommand, but not with
locatecommand. Hence, it allows you to search your whole file system when you might have no clue about the whereabouts of a given file.
Let's test my speed claim by searching for the
50-cloud-init.yaml file again, but using the locate and find commands.
$ time locate 50-cloud-init.yaml /etc/netplan/50-cloud-init.yaml Job locate 50-cloud-init.yaml CPU 99% user 0.95s system 0.02s total 0.97s $ time sudo find / -name '50-cloud-init.yaml' /etc/netplan/50-cloud-init.yaml Job sudo find / -name '50-cloud-init.yaml' CPU 99% user 2.49s system 11.73s total 14.25s
As you can see, the locate command did not even take a full 1 second to complete. The find command, on the other hand, took 14 seconds.
The main drawback of using
locate command is that, if a file has been created or modified or deleted after the database has been generated, the output of
locate command will be incorrect. Hence, requiring the constant update of the lookup database.
fd-find for faster multi-thread search
The fd-find tool consists of the
fd command, which is essentially the
find command, but written in Rust, with multi-threading.
With multi-threading enabled by default in
fd, your search queries will resolve much, much faster.
fdfind command has a very similar syntax compared to
find. Below is the syntax:
fdfind FILE_NAME LOCATION
Let's try searching for the '50-cloud-init.yaml' file using
fd command and also using
find command, to see how multi-threading helps.
$ time fdfind 50-cloud-init.yaml / /etc/netplan/50-cloud-init.yaml Job fdfind 50-cloud-init.yaml / CPU 369% user 3.19s system 12.10s total 4.14s $ time sudo find / -name '50-cloud-init.yaml' /etc/netplan/50-cloud-init.yaml Job sudo find / -name '50-cloud-init.yaml' CPU 99% user 2.72s system 11.76s total 14.51s
As seen in the result of 'find vs locate', find still has the same performance here with 14 seconds for completion. But, the
fdfind command comes to rescue your precious time by taking advantage of multi-threading.
Bonus tip: Finding files containing specific text
So far, whatever we have discussed is about finding files based on the filename or their properties. How about finding files that contain a particular text?
If you want to search for the contents of files, you'll have to use the grep command.
You can combine grep with find and exec commands based on your scenario. I will not dig deeper into that because it's a vast topic on its own.
I will show you a simple grep command that gives all the files that match a specific text in the current directory and its subdirectories.
grep -irl "text" .
- i - for case insensitive search
- r - for recursive search inside subdirectories
- l - to show only the file names, not the matching lines
Let me share a practical example. I have a massive bunch of bash scripts.
pratham@learnubuntu:~/Documents$ ls 3x10.sh count_lines.sh f5.txt hello.sh scope.sh addition.sh distros.sh factorial.sh iseven.sh timestamp.sh age.sh error.sh filetype.sh odd.sh user.sh array.sh f1.txt for.sh power.sh variables.sh break.sh f2.txt funarg.sh prime.sh var.sh c2f.sh f3.txt fun.sh reverse.sh wc char.sh f4.txt giga2mega.sh root.sh weather.sh
I want to see which scripts use the for loop.
pratham@learnubuntu:~/Documents$ grep -irl "for" . ./for.sh ./prime.sh ./break.sh ./var.sh ./odd.sh ./scope.sh
I discussed the three most common commands for finding files on Ubuntu.
find command is most reliable and versatile. It enables the use of many options like file size, case insensitivity, modification/creation time, read/write permissions, and much more. Likewise, the
fdfind command is a re-write in Rust with multithreading, making it perform faster.
locate commannd works with a database, with its own set of pros and cons.
You are free to use whichever command you want for personal usage. For scripting, I advise relying on the find command.