The Linux command line interface is a very powerful and flexible. What makes it so are the collection of tools that are part of it. Tools such as grep, awk, find, locate, and so on, make your life much easier when you have to find files, look for some text in a file or replace a word with another. Let’s look at the find command and see how you can use it to improve your command line search process.
In its simplest form the find command would be used like this
# find .
This command will give you a list of all the files and folders in the current directory. Beware that it will display all the files contained in sub folders as well, so the list could be really long. Hit the Control + C key combination to stop the display of more files.
This is the simplest usage of the find command. Using a combination of some of the command’s parameters and regular expressions you can make searching for files a lot more intelligent. For example, if you wanted to find all files whose name starts with image execute the following find based command:
# find . -name image\*
Here we have used the -name parameter in find to all filenames beginning with the word image. Note that this search is case sensitive. Modify the command to # find . -iname image\* to get results that are not case sensitive.
You can, of course, run wildcard searches for files with a certain extension. To find all file contained in the current folder and subfolders with a .php extension execute the following command, # find . -name \*.php. You can also run negative searches. For example, if you want to run a search for all files contained in a folder and its subfolders that do not end with the extension .php run the command # find . \! -name “*.php”. Notice the exclamation mark that we have introduced to run the negative search. This can be used for all other options as well.
One of the issues I often face when using the find command is that it searches all subfolders by default. Sometimes you just want it to search in a certain folder. To instruct find to do this you need to use the -maxdepth option. Using this option you can tell find how many levels in sub folders it should look at while running its search. So if you want it to search for files only in the current folder set maxdepth to zero. The command we used previously to search for all non PHP files would look something like this if we wanted to run it only in the current folder – # find . \! -name “*.php” -maxdepth 0. Increase the value of maxdepth to one and more when you want to increase the depth of the search. Similarly you can also set the -mindepth if you want to set an upper limit for the level of folders searched. You can use both of these together to run a search on lower level folders without getting results from other folders.
Search with Other Criteria
We looked at how to search for files using the -name option. The find command can search based on several other criteria also. for example, if you want to find all files owned by a certain user use the -user option. So if you want to find all PHP files owned by the user stewie in a certain folder use the command, # find . -name “*.php” -maxdepth 2 -user stewie.
Oftentimes you might be using the find command in shell scripts. The command itself throws few errors. However, when you run it as a normal user there are permission related errors that often pop up. For example, if you were to run a search for file in the root directory as a non root user you might see errors such as : Permission denied crop up. This can be quite annoying when using the command in a script. Although the find command itself does not seem to have a solution to this, we can easily fall back on a simple UNIX solution. Redirect all errors to good old /dev/null. So, a command like this:
# find / -name StewieGriffin\*
/root: Permission denied
/home/peterg: Permission denied
Would be converted to
# find / -name StewieGriffin\* 2>/dev/null
Now you can safely use the find command in your scripts, without worrying about errors cropping up in the output.
Find for Lazy People
I’m a lazy Linux user. I’m sure there are many more like me out there. I’m reasonably comfortable with the grep command. Although find has several very useful options by itself I find myself using it along with grep very often. The UNIX pipe option makes this very easy. So, if I wanted to search for a file containing the word “web” I would usually just run a search like this, # find . | grep web. This is the equivalent of # find . -name web. Similarly, if I wanted to run the same search, but make it so that it’s no longer case sensitive, I would run, # find . | grep -i web. In a similar way you can combine the find command with sed or awk. The beauty of the Linux or UNIX command line is that each of these tools is very powerful. The chance that you will have the time or the need to master them all is a bit small. Instead, you are better off learning one tool really well and get a basic idea of the rest, just in case you need them.