Linux: Find File by Name
Linux has a powerful command called find
. It can find any file (or directory), according to the search parameters we pass to it.
In this tutorial we'll explore how we can find files, based on their names.
Syntax of the Find Command
The syntax of the find
command is:
find [options] [/path/to/directory/] [search_parameters]
The options can change the behavior of the find
command. For example, there's an option -L
that will make it follow symbolic links. A symbolic link is a sort of "shortcut" on Linux; a "fake" file that leads to a real file, or directory, that exists in a different location. Similar to a shortcut we might have on a Windows desktop, that opens up the real program when we double click it.
Often, find
can be used without specifying any options. If we don't want any "advanced behavior," or fine-tuning of how the find
command works internally.
With /path/to/directory/
we specify the path to the directory we want to search through. This is also optional. For example, if we want to search for files in the directory we are currently in, we can omit this path to the directory.
And the search parameters are what matters most in a find
command. This is where we actually tell find
what to search for.
We can specify one, or more parameters here. For example, we can tell find
to search for files with some exact name. But we can also chain multiple parameters, and tell find
to search for files that end with the .jpeg
name, are at least 5 days old, and are larger than 10 megabytes.
Here's an example of a find
command where all three of these arguments are used:
- We'll use
-L
as an option. To makefind
follow symbolic links. - We'll specify the path to a directory,
/usr/share/
, to look for certain files here. - And the search parameter will be
-name motd
to find a file calledmotd
(a template file for the Message of the Day we might see when we log in to Linux machines).
find -L /usr/share/ -name motd
The output we'll get from this command might look something like this:
/usr/share/motd
/usr/share/base-files/motd
This is the result list, where find
shows us the full path to the matches it found: Files, or directories with this exact name, motd
.
A common mistake when using the find
command is to mix up the position of the path to the directory, with the position of the search arguments.
Meaning that a command like this is correct:
find /usr/share/ -name motd
But if we accidentally reverse the position of the path, with the search arguments, we end up with an incorrect command like this:
find -name motd /usr/share/
To solve this we can think of the find
command usage as:
Find where, what.
Meaning "where" is the first thing we need to specify (where is the directory?). And "what" is the second thing we have to specify (what name, or properties?).
It's similar to real life. If we want to go to a store, first we have to go to a general location on a map (the where part). And only afterwards we go to the specific store (the what part).
Find File (or Directory) with Exact Name
If we know the exact name of the file, or directory we're looking for, things are quite simple.
For example, let's say the file we are looking for is called index.html
. And it's somewhere in the /home/alex/
directory. To search for this all we need to do is run:
find /home/alex/ -name index.html
We can see it found the file at this path: /home/alex/template_projects/project1/
.
It's important to remember that, by default, find
will display both files, and directories with this name. For example, look what happens if we search for something called project1
:
find /home/alex/ -name project1
Now it found two results. And we know that the first result, /home/alex/template_projects/project1/
is a directory, since we saw that in the previous example. But what is /home/alex/projects/project1
? Is it a file, or directory? No way to know (just by looking at the result list), but we can solve this issue.
Search Only for Files with this Name
We can tell find
to filter results, and only show us files, not directories. All we need to do is add another search parameter: -type f
.
I'll create a directory called index.html
just to exemplify this:
Here's what happens if we do a regular search, and tell our command to find anything with the name index.html
:
find /home/alex/ -name index.html
It shows us both the directory (first result), and the file (second result).
But now let's add -type f
in our search parameters. Which tells find
to filter results, and only show files in the result list:
find /home/alex/ -name index.html -type f
Now we get only the file in the result list. And the directory is excluded.
Search Only for Directories with this Name
We can also filter in the opposite way. Instead of telling find
to only show us files, we can tell it to only show us directories. For that, we add -type d
to our search parameters:
find /home/alex/ -name index.html -type d
And this time we get only the directory:
Now that we know how to filter our results, and search only for files, let's see what we can do when we don't know the exact name of a file.
Find File by Name Pattern
The simplest pattern is when we know the "extension" of a file. If a file has a name like image.jpeg
we say that the extension of this file is .jpeg
.
.
in there. But we're going to call them extensions here, just to use familiar terms.Find File by Extension
Let's say we're looking for HTML files. That means we need to search for all files which have a name that ends with .html
. And that's quite easy. All we need to do is use the *
wildcard in our -name
search parameter. We'll soon talk about what *
does after we see an example.
In our scenario, to look for all files that end with the .html
extension, we could run a command like this:
find -name '*.html' -type f
Note we didn't specify the path to the directory here. Just to offer an example that even that part is optional. Since we're already in the /home/alex/
directory, our find
command will look for files in this current path. Of course, if we'd be in a different directory, we'd need to specify the full path here:
find /home/alex/ -name '*.html' -type f
There's a subtle difference in how we used the find
command this time though. We wrapped the name pattern in single quotes ' '
. Instead of *.html
we used '*.html'
. It's important to do this when using the *
wildcard. That's because in Bash (the default command interpreter on most Linux systems), the *
has a special meaning. And Bash would interpret it to mean something else rather than what we want here. It would replace *
with all files and directories in the current path. And we don't want that.
So by wrapping between single quotes we tell Bash:
Do not interpret this*
, just send it to the find command as a regular*
(don't expand it to all files and directories in the current path).
But what does this *
wildcard do in the *.html
pattern? It's like saying:
This part where the*
is, there can be any number of characters in this spot. 0 characters, 1, 2, 3, even 100 characters. But after that, it all ends with.html
.
So *
is like a "joker card" of sorts, that means "anything can appear here".
Find File that Begins with this Name
And now that we know what the *
wildcard does, we can find another use case for it. What if instead of the beginning, we place it at the end? Imagine something like scr*
.
Let's run it and see:
find -name 'scr*' -type f
This command will find any file that begins with the name scr
.
Find File that Ends with this Name
And we can do this in reverse, and find a file that ends with a certain name.
For example, to look for all files in the /usr/bin/
directory, that end with the name grep
:
find /usr/bin/ -name '*grep' -type f
Find File that Contains this Name
Imagine we're looking for programs that have something to do with ZIP compression. And we know that in their file names they must have the word zip
. Otherwise said:
- There can be any text before
zip
. - There can be any text after
zip
.
What's the "any card" that we know of? The *
wildcard, of course. All we need to do is add it in two places now: Before "zip" and after "zip". So we get to: *zip*
.
To look for any file that contains the word zip
we can use a command like this:
find /usr/bin/ -name '*zip*' -type f

Find File That Does Not Have this Name (Inverted Search)
Sometimes, instead of searching for files that match some pattern, we might want to look for files that do not match that pattern.
For example, if we're looking for PNG image files, we'll do a search for any file that ends with .png
.
But now imagine we're searching for anything except these images. And we don't want to be sitting there enumerating everything we want to find, like HTML files, CSS files, JavaScript files, and who knows what else. We just want to say: "Find me anything except files that match this pattern". Otherwise said: "Find all files that DO NOT match this pattern".
That's easy to do. We just add the -not
operator before that search pattern. For example, if we want to find any file in the /home/alex/projects
directory, that does NOT end with the .png
extension, we can use a command like this:
find /home/alex/projects/ -type f -not -name '*.png'
And we'll get a result list like this:
All files that do not end with ".png".
If we'd remove the -not
operator before our -name '*.png'
search pattern, we'd get this instead:
We can negate any search pattern. So any search pattern we can think of, we just add -not
before it, and we can find all files that do not match that pattern.
Make the Find Command Case Insensitive (Ignore Case of Letters)
There's a sort of unwritten rule on Linux: To have all file names written with all lowercase letters. Names like file
instead of File
or FILE
. But, as with anything in life, we will sometimes encounter exceptions to this rule.
And, unlike Windows, Linux considers the three examples above entirely different files. On Windows we cannot create a file called file
if we already have one called File
. It would be considered the same name, because Windows does not care about letter case. For that operating system, file
=File
=FILE
.
But, on Linux, here's me creating three files with these names:
And here they are, three separate files:
That's why the find
command has a small "problem". If we tell it to find something named file
, then it's very specific. It will find something with that exact name, in all lowercase letters, just as we wrote it:
find -name file
See? Just the first file was found. Because the other two files have different names. One begins with an uppercase "F", and the last one has all uppercase letters.
So how do we tell find
to search for all files with this name, no matter the letter cases? Otherwise said, how do we make find
case insensitive (ignore letter case)? Well, easily enough. We just use -iname
instead of -name
. Think of the i
in there as "ignore case".
For example, to find all files with the name file
, no matter what letters were used, uppercase, or lowercase, we can use this command:
find -iname file
And just like that, problem solved:
Now it found all three files.
Conclusion
find
is a powerful command. It can search for files, and directories, based on almost any criteria we might think of. In this tutorial, we explored searching for files based on the names, or name patterns they might have. But find
can also search according to how old a file is, its size, the permissions that are set for it, the owners it has, and so on.
We can run a command like this to read more about what the find
command can do:
man find

This text manual can be scrolled through with the Page Up and Page Down keys. And we can exit the manual by pressing q
.
If you're more of a visual learner, and you want to see advanced use cases of the find
command, you can check out one of our Linux courses:

See you in the next blog!