[Chapter 17] 17.2 Delving Through a Deep Directory Tree
Author: Jerry Peek, Tim O'Reilly & Mike Loukides
Date: 1998-08-04T21:38:16Z

#

| Chapter 17 Finding Files with find |

## 17.2 Delving Through a Deep Directory Tree

The first, and most obvious, use is find's ability to locate old, big, or unused files whose locations you've forgotten. However, what may be find's most fundamentally important characteristic is its ability to travel down subdirectories.

Normally the shell provides the argument list to a command. That is, UNIX programs are frequently given filenames and not directory names. Only a few programs can be given a directory name and march down the directory searching for subdirectories. The programs find, tar, du, and diff do this. Some versions of chmod, chgrp, ls, rm, and cp will, but only if a -r or -R option is specified.

In general, most commands do not understand directory structures, and rely on the shell to expand wildcards (15.2) to directory names. That is, to delete all files whose names end with a .o in a group of directories, you could type:

>     % rm *.o */*.o */*/*.o

Not only is this tedious to type, it may not find all of the files you are searching for. The shell has certain blind spots. It will not match files in directories whose names start with a dot. And, if any files match `*/*/*/*.o`, they would not be deleted.

Another problem is typing the above and getting the error `Arguments` `too` `long.` This means the shell would expand too many arguments from the wildcards you typed.

find is the answer to these problems.

A simple example of find is using it to print the names of all the files in the directory and all subdirectories. This is done with the simple command:

>     % find . -print

The first arguments to find are directory and file pathnames - in that example, a dot (`.`) is one name for the current directory (1.21). The arguments after the pathnames always start with a minus sign (`-`) and tell find what to do once it finds a file. These are the search operators. In this case, the filename is printed. You can use the tilde (`~`) (14.11) supported by the C shell, as well as particular paths. For example:

>     % find ~ ~barnett /usr/local -print

And if you have a very slow day, you can type:

>     % find / -print

which will list every file on the system. [This command is okay on single-user workstations with their own disks. It can tie up disks on multiuser systems enough to make users think of gruesome crimes! If you really need that list and your system has fast find (17.18), try the command `find '/*'` instead. -JP ]

find sends its output to standard output, so once you've "found" a list of filenames, you can pass them to other commands. One way to use this is with command substitution : (9.16)

    -d
    % ls -l `find . -print`

The find command is executed, and its output replaces the backquoted string. ls sees the output of find, and doesn't even know find was used.

Warning! | An alternate method uses the xargs (9.21) command. xargs and find work together beautifully. xargs executes its arguments as commands and reads standard input to specify arguments to that command. xargs knows the maximum number of arguments each command line can handle and does not exceed that limit. While the command:

>     % ls -ld `find / -print`

might generate an error when the command line is too large, the equivalent command using xargs will never generate that error:

>     % find / -print | xargs ls -ld

- BB

17.1 The find Command Is Great; The Problem Is Finding How to Use It |  | 17.3 Don't Forget -print