< Zurück | Inhalt | Weiter >

1.3.9 The find Command

If someone compiled a list of the top 10 most useful Linux utilities, find would most likely be near the top of the list. But it would also make the top 10 most confusing. Its syntax is very unlike other Linux utilities. It consists of predicates—logical expressions that cause actions and have true/false values that determine if the rest of the expression is executed. Confused? If you haven’t used find before you probably are. We’ll try to shed a little light by showing a few examples.


find . -name '*frag*' -print


This command looks for a file whose name contains frag. It starts looking in the current directory and descends into all subdirectories in its search.


find /over/there . /tmp/here -name '*frag*.java' -print


This command looks for a file that has frag in its name and ends with .java. It searches for this file starting in three different directories—the current directory (“.”), /over/there, and /tmp/here.


find . -name 'My[A-Z]*.java' -exec ls -l '{}' \;


Starting in the current directory, this command searches for a file whose name begins with My followed by an uppercase alphabetic character followed by anything else, ending with .java. When it finds such a file, it will execute a command—in this case, the ls command with the -l option. The braces are replaced with the name of the file that is found; the “\;” indicates to find the end of the command.

The -name is called a predicate; it takes a regular expression as an argu- ment. Any file that matches that regular expression pattern is considered true, so control passes on to the next predicate—which in the first example is simply

-print that prints the filename (to standard out) and is always true (but since no other predicate follows it in this example, it doesn’t matter). Since only the names that match the regular expression cause the -name predicate to be true, only those names will get printed.

There are other predicates besides -name. You can get an entire list by typing man find at a command prompt, but Table 1.3 lists a few gems, to give you a taste of what find can do.

Let’s look at an example to see how they fit together:


Table 1.3 Some find predicates


image

Option


image

-type d

-type f

-mtime -5


-atime -5


-newer myEx.class

-size +24k

Explanation

Is true if the file is a directory.

Is true if the file is a plain file (e.g., not a directory).

Is true if the file is less than five days old, that is, has been modified within the last five days. A +5 would mean older than five days and a 5 with no sign means exactly five days.

Is true if the file was accessed within the last five days. The + and - mean greater and less than the specified time, as in the previous example.

Is true if the file is newer than the file myEx.class.

Is true if the file is greater than 24K. The suffix c would mean bytes or characters (since b stands for 512-byte blocks in this context). The + and - mean greater and less than the specified size, as in the other examples.


image



$ find . -name '*.java' -mtime +90 -atime +30 -print

./MyExample.java

./old/sample/MyPrev.java

$


This command printed out the names of two files that end with .java found beneath the current directory. These files hadn’t been modified in the last 90 days nor accessed within the last 30 days. The next thing you might want to do is to run this command again adding something at the end to remove these old files.


$ find . -name '*.java' -mtime +90 -atime +30 -print -exec rm '{}' \;

./MyExample.java

./old/sample/MyPrev.java

$