How to find a file in the filesystem from the command line?
I’d like to find where a file (with a partially-known filename) is in the file system. I’d like to know how to do this from the command line, rather than using a GUI utility. In Windows, I’d run the following:
Well, there’s quite obviously more than one way to skin this cat. I’m still a little curious to know if there’s a way to do it with ls ?
4 Answers 4
locate filename find -name '*filename*' echo **/*filename* ls -ld **/*filename*
(Read on for the main terms and conditions. Read the manual for the fine print.)
Listing the contents of a directory is kind of a secondary feature of ls . The main job of ls , the one that takes up most of its complexity, is fine-tuning its display. (Look at the manual and compare the number of options related to choosing what files to display vs. the number of options that control what information to display about each file and how the display is formatted. This is true both of GNU ls which you’ll find on Linux, and of other systems with fewer options, since the early days.)
The default mode of ls is that when you pass it a directory, it lists the files in that directory. If you pass it any other type of file (regular file, symbolic link, etc.), it lists just that file. (This applies to each argument separately.) The option -d tells ls never to descend into a directory.
ls does have an option -R that tells it to list directories recursively. But it’s of limited applicability, and doesn’t allow much filtering on the output.
The very first tool to perform pattern matching is the shell itself. You don’t need any other command: just type your wildcards and you’re set. This is known as globbing.
Traditionally, wildcards were limited to the current directory (or the indicated directory: echo /some/where/*filename* ). A * matches any file name, or any portion of file name, but *.txt will not match foo/bar.txt . Modern shells have added the pattern **/ which means “in this directory, or in any directory below it (recursively)”. With bash, for historical compatibility reasons, this feature needs to be explicitly enabled with shopt -s globstar (you can put this line in your ~/.bashrc ).
The echo command just echoes the list of file names generated by the shell back at you. As an exception, if there is no matching file name at all, the wildcard pattern is left unchanged in bash (unless you set shopt -s nullglob , in which case the pattern expands to an empty list), and zsh signals an error (unless you set setopt nullglob , or setopt no_no_match which causes the pattern to be left unchanged).
You may still want to use ls for its options. For example, ls can give indications about the nature or permissions of the file (directory, executable, etc.) through colors. You may want to display the file’s date, size and ownership with ls -l . See the manual for many more options.
The traditional command to look for a file in a directory tree is find . It comes with many options to control which files to display and what to do with them. For example, to look for files whose name matches the pattern *filename* in the current directory and its subdirectories and print their names:
find /some/dir -name '*filename*' -print
-print is an action (most other actions consist of executing a command on the file); if you don’t put an action, -print is implied. Also, if you don’t specify any directory to traverse ( /some/dir above), the current directory is implied. The condition -name ‘*filename’ says to list (or act on) only the files whose name matches that pattern; there are many other filters, such as -mtime -1 to match the files modified in the last 24 hours. You can sometimes omit the quotes on -name ‘*filename*’ , but only if the wildcard would not match any file in the current directory (see above). All in all, the short form is
Another useful tool when you know (part of) the name of a file is locate . This tool queries a database of file names. On typical systems, it’s refreshed every night. The advantage of locate over find / is that it’s a lot faster. A downside is that its information may be stale. There are several implementations of locate which differ in their behavior on multi-user systems: the basic locate program indexes only publicly-readable files (you may want to run the companion updatedb to make a second database that indexes all the files in your account); there are other versions (mlocate, slocate) that index all files and have the locate program filter the database to only return the files you can see.
Sometimes you think that a file is provided by a package in your distribution, you know (part of) the name of the file but not the name of your package, and you’d like to install the package. Many distributions provide a tool for that. On Ubuntu, it’s apt-file search filename . For equivalent commands on other systems, check the Pacman Rosetta.
How to use the Find command in Linux
In this tutorial, you will learn how to use the find command to find files and directories on your Linux filesystems. You will also learn how to execute commands against files returned by the find command.
Basic Find
The find command can used to find files, directories or both. By default it will match a string against both files and directories.
The basic syntax of the find command looks like the following
For example, to search for a file or directory named “tutorials” from your home directory, you would execute the following command.
Finding a File
To narrow your search down to files only you use the -type flag with the find command. Using the example above, in order to find just files with the name “tutorials” you would execute the following command.
find ~/my/files -name "tutorials" -type f
The -type f instructs the find command to only match the -name string against files.
Finding Files of a Specific Size
To narrow your results, the find command can search for files matching a specific size. The size can be represented in kilobytes, megabytes, gigabytes, terabytes, or even petabytes.
The following example searches for files that are 2 gigabytes in size, rounded up by blocks of 512 bytes.
find /my/media -type f -size 2G
Finding Files Owned by a User
Finding files based on ownsership is also possible. We have the option of searching by username or even uid (user id).
To find files owned by a user named jsmith, you use the -flag in your comand with the name of the user.
find /opt/service -user jsmith
Alternatively, to search by user ID instead you the -uid flag.
Finding Files based on Age
Have you ever needed to find a file that was created within the last few minutes or day? Thankfully, the find command also supports finding files and directories based on age.
To find a file a file created within the last 10 minutes you use the -newerct command.
find /var/log -newerct `10 minutes ago` -print
Finding a Directory
Alternative, to narrow your search down to directories only, you can use use the -type flag with the value d . Files will be ignored and they will not be included in your search results.
find ~/ -name "tutorials" -type d
Executing Commands Against Found Files
There are many scenarios where you find yourself needing to execute a command against the returned file list. This may be to set permissions on directories only of a given path, or to copy matching files to a specific location.
To execute commands against discovered files and directories you use the exec flag.
The two brackets ‘ <> ‘ near the end of the command are placeholders. The placeholders will be replaced by the files and/or directories that are returned by the find command. The ‘ \; ‘ at the end terminates the find command.
To copy files from your home directory that contain the word “tutorial” in their filename to /temp , you would execute the following find command.
find ~/ -name="*tutorials*" -type f -exec cp <> /temp \;
Whenever find matches a file found in your home directory or any of its child directories, it will execute the cp command to copy it to the /temp directory.
Conclusion
The find command in Linux is a very powerful tool. You can find virtually anything on your filesystems, whether its a file or directory. You can also execute commands against the files or directories that you find.