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.

  1. find: when you know where to search
  2. locate: when you don't know where to search
  3. 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 accessed n number of minutes ago
  • -mmin n: File was last modified n number of minutes ago
  • -type: The type of a file. Use d, f and l for a directory, file and a symbolic link, respectively.
  • -empty: An empty file or a directory
  • -size n: File of size n. Use c, k, M and G 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 the find command
  • Specifying a directory to search in is required with find command, but not with locate 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.

Use Locate Command to Quickly Find Files in Ubuntu
When you want a simple file search by its name, locate is sufficient. Learn how to use locate command in Ubuntu.

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.

[email protected]:~/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.

[email protected]:~/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.