Linux Command Line: Searching
Searching for Files with locate locate
By now you'll probably be wondering - where is the search bar on the Linux Command Line?
Before we get started with the
locate command, you need to set up a database that the shell can look for the files you are searching for.
Setting up a database to search from
If you run something like
locate 'html' for the first time, you'll get an error message similar to below (Mac OS X).
WARNING: The locate database (/var/db/locate.database) does not exist. To create the database, run the following command: sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist Please be aware that the database can take some time to generate; once the database has been created, this message will no longer appear.
If you're runnign Linux, you'll have an error such as this.
locate: can not start () `/var/lib/mlocate/mlocate.db': No such file or directory
Both of these errors mean that you haven't created a locate database to store all your filenames. Without this, the shell has nowhere to look. Thus, simply run
updatedb as the root user (if you're using Linux), or type in the command presented above (for Mac OS X). This will generate an indexed database for you. Note: it may take a while to generate, and will be running in the background, so just sit tight for a few minutes.
Updating your database
The database is recomputed daily, and contains the pathnames of all files which are publicly accessible. It runs as a cron job, which is a task that is run by the cron daemon periodically.
With this, you may find that some of your most recent files don't appear immediately with the locate file. Thus, to update your database manually, you can use the
updatedb command. You may need to install the
The locate command
Once we have our database set up, we can use the
The locate command quickly searches in the database for a substring matching a specified pattern. The shell then displays every absolute pathname of the files found.
$ locate 'html'
This command would locate all files that start with the name "html" in all directories listed in our database.
We can also use wildcards to be more specific with what we want.
$ locate 'h*.html' # List all .html files starting with an h.
To narrow our results further, we can pipeline the results with
grep and specify the name of another folder.
$ locate '*.html' | grep share
This will locate all files with the .html extension that also has share in its path name.
Options with locate
Here are a few options that you may find helpful.
- Suppress error messages that might arise from not having permissions.
- Specify a number after to limit the number of outputs.
- For case insensitive search.
You may find yourself limited to your search options with
locate. Let's look at how we can do a more advanced search with the
Searching for Files with find find
locate command is useful and efficient if you need to locates a file based on its pathname. However, if you want more flexibilty and power in your search, you can use the
There are three main parts of the
- Where to look
Below is an example of a typical
Let's go through this piece-by-piece.
Where to look
The first argument is which directories we want to look in. By default, the shell searches recursively through the directory specified.
$ find . . ./file1.txt ./file2.txt
This simple example will list out all file names and directories in the current folder (
.). You may place a relative or an absolute pathname here, or your home directory (
If you have a lot of files and want to see how many files are being listed, we can use the
$ find . | wc
3 3 32
This shows us that this particular find command returns 3 words, 3 lines and 32 characters. In other words, we have just three files (including folders) being outputted.
Now, it's probably not manageable to list out all contents, or as useful to just
wc results. Additionally, we wouldn't want to pipe our results as that can be too messy of a command.
Luckily we can use criteria to filter our results directly through the
Specifying file type
A useful option we can use is
type, which is used to filter based on the type of file.
To specify a directory or file, we simply pass a
$ find ~ -type d # List all directories within our home $ find ~ -type f # List all files within our home
You can also use a
l type for symbolic links.
Specifying file name
In addition to file type, we can specify name with the
-name option. We can add wildcards for more flexibility and power.
$ find ~ -type f -name "*.html" # All files in our home directory with a .html extension
For the case-insensitive option, we use
Specifying file size
To specify a file size, we use the
-size option. Before typing out the size, place either a
+ symbol. This specifies if you want results that are smaller or larger than the given value.
$ find ~ -type f -name "*.html" -size -3M # Search for all files with an .html extension with a size < 3 megabytes.
There are plenty of other options that are available to suit your needs. Remember to check out the
man page for a list of all of them. Here are some of our favorites that you may find useful.
- -cmin n
- files or directories that were modified n minutes ago.
- files or directories that are empty.
- -mtime n
- Files or directories that were modified within n*24 hours ago.
- -mmin n
- Files or directories modified at least +n minutes ago and less than -n minutes ago.
- -maxdepth n
- Descend at most n levels into a directory.
- -mindepth n
- Descend at least n levels into a directory.
- Don't traverse directories that are mounted on other file systems.
- -newer file
- Files and directories that are newer than file.
- -perm mode
- Find files/directories that match a specified mode.
- -user name
- Find files or directories belonging to a name.
- Can also use the -uid or -guid to find by user ID and group ID.
We can combine logical operators to further specify our search specifications; to specify precedence, surround the statements with
- Both expressions are true.
- Either expression must be true.
For example, if we wanted our search criteria to match two criteria, we can link a statement with an
-and. If we just want one of the criteria to be satisfied, use
$ find . -type f \( -name "*.html" \) -or \( -name "*.php" \) # Return all files with a .html extension and readable by others $ find . -type f \( -name "*.html" -and -perm -o=r \)
Lastly, we have our actions, where apply a command to the files that have been found.
- Delete the currently matching file.
ls -dilson matching files.
- Output the full pathname of match file.
- Quit once a match is made.