Find Files and Commands in Linux

CompTIABeginner
Practice Now

Introduction

In this lab, you will master essential techniques for locating files and commands within the Linux command-line environment. You will begin by using the powerful find command, learning how to perform basic searches by name and leverage wildcards for more flexible pattern matching. This hands-on approach will guide you through creating a sample directory structure to safely practice your searching skills.

Building on this foundation, you will explore how to execute commands on your search results using -exec and xargs. The lab also covers alternative and specialized search tools, including the fast, database-driven locate command, whereis for finding command binaries and manuals, and utilities like alias, which, and type to analyze the command execution path. By the end, you will be proficient in choosing the right tool for any file or command search task in Linux.

Perform Basic File Searches Using find and Wildcards

In this step, you will learn how to use the find command, one of the most powerful tools in the Linux command-line for searching for files and directories. We will start with basic name-based searches and introduce wildcards to find patterns of files.

First, let's create a dedicated directory and some sample files for our practice. This ensures we have a controlled environment to see how find works without affecting other parts of the filesystem.

  1. Ensure you are in the correct starting directory. All work for this lab will be done inside ~/project.
cd ~/project
  1. Create a new directory named find_lab and navigate into it.
mkdir find_lab
cd find_lab
  1. Now, let's create a set of files and a subdirectory to search through. We'll use the touch command to create empty files and mkdir for the directory.
touch file1.txt file2.log report.txt File1.TXT
mkdir subdir
touch subdir/file3.txt subdir/another.log

You can verify the structure with the ls -R command, which lists files in the current directory and its subdirectories recursively.

ls -R

You should see an output similar to this:

.:
File1.TXT  file1.txt  file2.log  report.txt  subdir

./subdir:
another.log  file3.txt

Now that our test environment is ready, let's start searching.

The basic syntax for the find command is find [path] [expression]. The [path] tells find where to start searching, and the [expression] defines what to look for.

Searching by Exact Filename

To find a file by its exact name, you use the -name expression. Let's find the file report.txt. We will use . as the path, which tells find to start searching from the current directory.

find . -name "report.txt"

The output will show the path to the file it found:

./report.txt

Searching with Wildcards

Wildcards allow you to search for files based on patterns. The most common wildcard is the asterisk (*), which matches any sequence of characters.

It's a best practice to enclose the pattern in double quotes (") to prevent the shell from interpreting the wildcard before the find command can use it.

Let's find all files that end with the .txt extension.

find . -name "*.txt"

find will search recursively through the current directory (.) and all its subdirectories:

./file1.txt
./report.txt
./subdir/file3.txt

Notice that File1.TXT was not found because -name performs a case-sensitive search. To perform a case-insensitive search, use the -iname (insensitive name) expression.

find . -iname "*.txt"

Now, the output includes all files ending in .txt, regardless of case:

./file1.txt
./report.txt
./File1.TXT
./subdir/file3.txt

Searching by File Type

You can also instruct find to look only for specific types of filesystem objects, like files or directories, using the -type expression. Use -type f for regular files and -type d for directories.

Let's find only the directories within our current location.

find . -type d

The output lists the current directory (.) and the subdir we created:

.
./subdir

You can combine expressions to create more specific searches. For example, to find all files (not directories) that end in .log:

find . -type f -name "*.log"

This command will find all items that are files AND have a name ending in .log.

./file2.log
./subdir/another.log

You have now learned the basics of using find with name patterns and type filters. In the next steps, we will explore more advanced capabilities of this command.

Execute Actions on Search Results with find -exec and xargs

In this step, you'll go beyond simply listing files. You will learn how to execute commands directly on the files found by the find command. This is a powerful technique for performing bulk operations, such as changing permissions, deleting files, or running custom scripts. We will cover two primary methods: the -exec option of find and the xargs command.

We will continue working in the ~/project/find_lab directory from the previous step. First, ensure you are in the correct directory.

cd ~/project/find_lab

Using find -exec

The -exec option allows you to run an arbitrary command for each file that find locates. The syntax can seem a bit unusual at first:

find [path] [expression] -exec [command] {} \;

  • [command]: The command you want to run (e.g., ls -l, rm, chmod).
  • {}: This is a special placeholder. find replaces {} with the full path of the current file it has found.
  • \;: This is a required terminator for the -exec command. The backslash (\) is necessary to prevent the shell from interpreting the semicolon as a special character.

Let's try it. We'll find all files with the .txt extension and run ls -l on each one to see its detailed information.

find . -name "*.txt" -exec ls -l {} \;

The output shows the result of ls -l being run twice, once for each .txt file found:

-rw-rw-r-- 1 labex labex 0 Jun 26 09:45 ./file1.txt
-rw-rw-r-- 1 labex labex 0 Jun 26 09:45 ./report.txt
-rw-rw-r-- 1 labex labex 0 Jun 26 09:45 ./subdir/file3.txt

For safety, find provides a -ok option, which works just like -exec but prompts you for confirmation before executing the command on each file. This is highly recommended when performing destructive operations like deleting files (rm).

Let's try to remove the .log files we created earlier, but this time using -ok for safety.

find . -name "*.log" -ok rm {} \;

For each file found, find will ask for your confirmation. Type y and press Enter to approve the deletion.

< rm ... ./file2.log > ? y
< rm ... ./subdir/another.log > ? y

After confirming, you can verify that the files are gone by listing the contents of the directory.

ls -R
.:
File1.TXT  file1.txt  report.txt  subdir

./subdir:
file3.txt

Using xargs

An alternative to -exec is to pipe the output of find to the xargs command. xargs reads items from standard input (the file paths provided by find) and executes a specified command with those items as arguments.

The main advantage of xargs is efficiency. While -exec ... \; runs the command once for every single file, xargs groups the file paths and runs the command fewer times with many arguments at once.

First, let's recreate the log files we just deleted so we have something to work with.

touch file2.log subdir/another.log

Now, let's use find and xargs to list the details of our .log files.

find . -name "*.log" | xargs ls -l

The output is similar to the -exec example, but the command structure is different:

-rw-r--r-- 1 labex labex 0 <date> <time> ./file2.log
-rw-r--r-- 1 labex labex 0 <date> <time> ./subdir/another.log

Like find -ok, xargs also has a "prompt" mode using the -p option. It will display the command it's about to run and ask for your confirmation.

Let's use this to delete the .log files again.

find . -name "*.log" | xargs -p rm

xargs will group the files into a single rm command and ask for your confirmation. Type y and press Enter.

rm ./file2.log ./subdir/another.log ?...y

You have now successfully used both -exec and xargs to act upon search results, a fundamental skill for automating tasks in Linux.

Use locate and updatedb for Fast Database-Driven Searches

In this step, you will learn about an alternative to find called locate. While find searches the filesystem in real-time, locate searches a pre-built database of file paths. This makes locate significantly faster, but with a crucial trade-off: it can only find files that existed when the database was last updated.

We will continue our work in the ~/project directory. First, let's ensure the necessary tools are installed.

  1. The locate command is provided by the mlocate package, which may not be installed by default. Run the following command to update your package list and install it. You will use sudo because this is a system-wide installation.
sudo apt-get update && sudo apt-get install -y mlocate

You will see package installation progress, which is normal.

  1. Now, let's navigate into our test directory from the previous steps.
cd ~/project/find_lab
  1. Try to find the report.txt file using locate.
locate report.txt

In many systems, the locate database is automatically updated, so you might see the file immediately:

/home/labex/project/find_lab/report.txt

If you see the file path, it means the database already contains information about your recently created files. This can happen when the system automatically runs database updates in the background.

  1. If you didn't see any output in step 3, the database needs to be updated manually. Use the updatedb command to rebuild the database:
sudo updatedb

This command produces no output, but it works in the background. It may take a few moments to complete.

  1. After running updatedb (if needed), try the locate command again:
locate report.txt

Now it should find and display the path to the file:

/home/labex/project/find_lab/report.txt

Understanding Local Database Limitations

Let's explore what happens when you create new files after the database was last updated.

  1. First, let's create a new file in our find_lab directory.
touch special_report.pdf
  1. Try to locate this new file:
locate special_report.pdf

If the system database was recently updated, you might see the file. If not, there will be no output because the database doesn't know about this newly created file yet.

  1. You can force an update of the system database:
sudo updatedb
  1. Now try locating the file again:
locate special_report.pdf

You should now see:

/home/labex/project/find_lab/special_report.pdf

Understanding Database Update Frequency

The key takeaway is that locate depends on the freshness of its database. In production systems:

  • The system typically updates the locate database automatically (often daily via cron jobs)
  • You can manually update it with sudo updatedb when you need immediate results
  • locate is extremely fast because it searches a pre-built index rather than scanning the filesystem
  • For finding very recently created files, find might be more reliable since it searches in real-time

You've now learned how locate provides lightning-fast searches by using a pre-built database, and understand the importance of keeping that database current with updatedb.

Locate Command Binaries and Manuals with whereis

In this step, you will learn to use whereis, a specialized command for locating the binary, source, and manual page files for a command. Unlike find or locate, which are for general-purpose file searching, whereis is optimized for quickly finding the essential files associated with a system command. It works by searching a predefined list of standard Linux directories, making it extremely fast.

Let's start by exploring the whereis command. You can be in any directory for this, as whereis does not search relative to your current location. We'll stay in the ~/project directory for consistency.

cd ~/project
  1. Let's find the locations for the passwd command, which is used to change user passwords.
whereis passwd

The output shows the command name, followed by the paths to its binary executable and its associated manual pages.

passwd: /usr/bin/passwd /etc/passwd /usr/share/man/man1/passwd.1.gz /usr/share/man/man5/passwd.5.gz
  • /usr/bin/passwd: This is the executable program.
  • /etc/passwd: This is the system's user database file, which the passwd command interacts with. whereis often includes important configuration files in its results.
  • /usr/share/man/...: These are the compressed manual pages for the command.
  1. You can filter the results to show only specific types of files. To see only the binary files associated with passwd, use the -b (binary) flag.
whereis -b passwd

This narrows down the output to just the executable and related files, excluding the man pages.

passwd: /usr/bin/passwd /etc/passwd
  1. Similarly, to find only the manual pages, use the -m (manual) flag. This is useful when you want to know what documentation is available for a command.
whereis -m passwd

The output now lists only the man page locations.

passwd: /usr/share/man/man1/passwd.1.gz /usr/share/man/man5/passwd.5.gz
  1. It's important to understand the limitations of whereis. It only searches standard system directories. Let's try to find the report.txt file we created in our find_lab directory.
whereis report.txt

The command returns only the name of the file, but no path:

report.txt:

This happens because report.txt is in your home directory (~/project/find_lab), which is not a standard location for system binaries or man pages. This demonstrates the key difference: use find or locate for your personal or project files, and use whereis to investigate system commands.

You have now learned how to use whereis to quickly locate the files that make up a Linux command, a useful skill for system administration and troubleshooting.

Analyze Command Paths with alias, which, and type

In this final step, we will explore how the shell determines which command to execute when you type its name. This isn't always as simple as finding a file on the disk. The shell has a specific order of precedence: it first checks for aliases, then shell built-in commands, and finally searches the directories in the system's $PATH for an executable file. You will learn to use alias to create command shortcuts, and which and type to diagnose what a command name actually points to.

Let's begin by creating a temporary alias to see how it affects command execution. We will stay in the ~/project directory.

  1. An alias is a user-defined shortcut for another command. Let's create an alias that makes the pwd command (print working directory) execute the date command instead.
alias pwd='date'
  1. Now, execute the pwd command.
pwd

Instead of printing your current directory, it prints the current date and time, because the alias takes precedence.

<current date and time>

Investigating with which and type

Now, imagine you didn't know about the alias. How would you troubleshoot why pwd is misbehaving? This is where which and type are useful.

  1. The which command locates an executable file in the directories listed in the $PATH environment variable.
which pwd

The output will show:

pwd: aliased to date
  1. The type command is more comprehensive. It's a shell built-in that describes how the shell will interpret a command name, including aliases and built-in functions.
type pwd

This command correctly identifies the situation:

pwd is an alias for date
  1. To see all possible commands that match a name, you can use the -a (all) flag. This is especially powerful with type.
type -a pwd

This reveals the full hierarchy for the pwd command name:

pwd is an alias for date
pwd is a shell builtin
pwd is /usr/bin/pwd
pwd is /bin/pwd

This output tells you the shell's order of preference: it will use the alias first. If the alias didn't exist, it would use the shell's built-in pwd command. If neither of those existed, it would execute the program located at /usr/bin/pwd.

Removing an Alias

Finally, let's clean up our experiment by removing the alias.

  1. The unalias command removes an alias definition from the current shell session.
unalias pwd
  1. Now, run pwd and type pwd again to confirm that everything is back to normal.
pwd

Output:

/home/labex/project
type pwd

Output:

pwd is a shell builtin

You have now learned how to create and remove aliases and, more importantly, how to use which and type to understand exactly what command the shell will run.

Summary

In this lab, you learned to search for files and directories across the Linux filesystem. You started with the powerful find command, using name-based criteria and wildcards for basic searches, and then advanced to executing commands on the search results with -exec and xargs. You also explored the locate command as a faster, database-driven alternative, learning how to maintain its database with updatedb.

Furthermore, the lab covered techniques for locating and analyzing commands. You used whereis to find the location of command binaries and their manual pages. To understand the command execution path, you learned to use which to identify the specific executable being called and type to determine if a command is an alias, a built-in, or a file, while also analyzing how aliases affect command behavior.