Programs for finding files

Finding files with grep

There are many powerful programs for finding information on a Linux system, depending on what you know. Say for example, you were working on your resume in your home directory, but can't remember the name of the file you saved it in. In this case, you likely know some of the text in the file, and you could use grep to find it (and the file).

Example 8-2. Finding text with grep


$ grep "Work experience" *
...

The above example would search every file (indicated by the *) for the exact text ``Work experience'' and return any matching lines along with the names of the files where the match occurred. This is a simple use of grep, but one that is very common. Grep is also capable of very sophisticated searches using objects called regular expressions. Regular expressions are an advanced topic of their own; for a beginner it is probably best to search only for plain words without punctuation. In particular, the symbols for "^$.*+?()[]{}\" have special meaning in searches and should be avoided until you have learned something about regular expressions.

Finding files with locate

If you know the name of the file you are looking for, but do not know what directory it is in, the simplest and fastest command for finding it is usually locate. It is commonly paired with grep to make the search more selective.

Example 8-3. Finding with locate


$ locate printcap
/etc/printcap
/etc/printcap.dpkg-dist
/usr/share/doc/lpr/examples/printcap
/usr/share/man/man5/printcap.5.gz
$ locate .bashrc | grep dbindner
/home/ldap/dbindner/.bashrc
/home/ldap/dbindner/.bashrc.bak

In the example above, there are 4 files that match the pattern ``printcap'' in the first search. In the second search, it is important to remember that there are usually many .bashrc files on a system; almost every user is guaranteed to have one which the locate command will happily report. The grep command is used to limit the files to those also having the pattern ``dbindner'' in them, a much more manageable set.

Note: Rather than search the entire system for a file, locate uses a pre-compiled database of files. The database is typically updated once a day (by searching the entire system sometime during the night). This makes locate very fast, but it also means that locate cannot be used to find a file you created (and lost) 15 minutes ago.

Finding files with whereis and which

On many unix systems, there will be multiple sets of the same programs and tools installed. For example, there may be two ps programs, one conforming to AT&T Unix conventions and another BSD-style version. Although this is less common on Linux systems, it can still sometimes be helpful to know exactly which program is being run when you type a command. The commands for learning this information are whereis and which.

Example 8-4. Using whereis and which


$ whereis chfn
chfn: /usr/bin/chfn /usr/local/bin/chfn /usr/share/man/man1/chfn.1.gz
$ which chfn
/usr/local/bin/chfn

Here there are two chfn programs. The one that came with the system is /usr/bin/chfn, and another one has been installed in /usr/local/bin/chfn. The which command identifies the ``local'' one as the default. That is, if you type chfn (the command to change your finger information), it will use the copy in /usr/local/bin. The other chfn program can still be used, but you must type the entire pathname of the program to run it.

Finding files with find

The heavyweight champion of finding programs is undoubtedly find. It is a very flexible program that few people (even advanced people) fully take advantage of. For the beginner however, basic use of find is still quite straightforward.

The syntax of a find command is find path expression. The path indicates where the search should begin (the search will recursively include all of the subdirectories of the starting spot) and is commonly either / for searching the whole filesystem or . for searching under the current directory. The expression indicates how the search is to be performed and the action to take on matches. Typical use would be:

Example 8-5. Finding a file with find


$ find . -name .bashrc -print
./.bashrc
$ find . -iname "*Hello*" -print
./octave/hello.cc
./octave/hello.o
./octave/hello.oct
$ find / -name .bashrc -print 2>/dev/null | grep dbindner
/home/ldap/dbindner/.bashrc

The first search is straightforward. It prints the names of files that match .bashrc exactly. The second performs a case insensitive name match (-iname) for filenames containing ``Hello'' (the stars mean match anything at the beginning and end) and prints the results.

The final search looks through the whole filesystem for .bashrc files and then ``greps'' for those containing the string dbindner. This command takes some time because the whole filesystem has to be searched. The ``2>/dev/null'' part of the command tells the shell to ignore any error output that the find command might generate. Find will print warnings when encountering directories we do not have the ability to search, and this will effectively ignore those.