Finding Files in Ubuntu Command Line
Looking for a specific file in the terminal? Here are all the essentials you need to know about finding files in the Ubuntu command line.
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!
find command
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 accessedn
number of minutes ago-mmin n
: File was last modifiedn
number of minutes ago-type
: The type of a file. Used
,f
andl
for a directory, file and a symbolic link, respectively.-empty
: An empty file or a directory-size n
: File of sizen
. Usec
,k
,M
andG
for 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 ~/Pictures/self
directory.
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 -name
(or -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
command.
$ 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
The -name
and -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:
sudo updatedb
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
The syntax 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:
locate FILE_NAME
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 /etc/netplan
directory.
The two main advantages of using the locate
command over using find
command are as follows:
- The
locate
command is incredibly fast compared to thefind
command - Specifying a directory to search in is required with
find
command, but not withlocate
command. 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.
The 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
Conclusion
I discussed the three most common commands for finding files on Ubuntu.
The 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.
Finally, the 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.