Go to the previous, next section.

Common Tasks

The sections that follow contain some extended examples that both give a good idea of the power of these programs, and show you how to solve common real-world problems.

Viewing And Editing

To view a list of files that meet certain criteria, simply run your file viewing program with the file names as arguments. Shells substitute a command enclosed in backquotes with its output, so the whole command looks like this:

less `find /usr/include -name '*.h' | xargs grep -l mode_t`

You can edit those files by giving an editor name instead of a file viewing program.

Archiving

You can pass a list of files produced by find to a file archiving program. GNU tar and cpio can both read lists of file names from the standard input--either delimited by nulls (the safe way) or by blanks (the lazy, risky default way). To use null-delimited names, give them the `--null' option. You can store a file archive in a file, write it on a tape, or send it over a network to extract on another machine.

One common use of find to archive files is to send a list of the files in a directory tree to cpio. Use `-depth' so if a directory does not have write permission for its owner, its contents can still be restored from the archive since the directory's permissions are restored after its contents. Here is an example of doing this using cpio; you could use a more complex find expression to archive only certain files.

find . -depth -print0 |
  cpio --create --null --format=crc --file=/dev/nrst0

You could restore that archive using this command:

cpio --extract --null --make-dir --unconditional \
  --preserve --file=/dev/nrst0

Here are the commands to do the same things using tar:

find . -depth -print0 |
  tar --create --null --files-from=- --file=/dev/nrst0

tar --extract --null --preserve-perm --same-owner \
  --file=/dev/nrst0

Here is an example of copying a directory from one machine to another:

find . -depth -print0 | cpio -0o -Hnewc |
  rsh other-machine "cd `pwd` && cpio -i0dum"

Cleaning Up

This section gives examples of removing unwanted files in various situations. Here is a command to remove the CVS backup files created when an update requires a merge:

find . -name '.#*' -print0 | xargs -0r rm -f

You can run this command to clean out your clutter in `/tmp'. You might place it in the file your shell runs when you log out (`.bash_logout', `.logout', or `.zlogout', depending on which shell you use).

find /tmp -user $LOGNAME -type f -print0 | xargs -0 -r rm -f

To remove old Emacs backup and auto-save files, you can use a command like the following. It is especially important in this case to use null-terminated file names because Emacs packages like the VM mailer often create temporary file names with spaces in them, like `#reply to David J. MacKenzie<1>#'.

find ~ \( -name '*~' -o -name '#*#' \) -print0 |
  xargs --no-run-if-empty --null rm -vf

Removing old files from `/tmp' is commonly done from cron:

find /tmp /var/tmp -not -type d -mtime +3 -print0 |
  xargs --null --no-run-if-empty rm -f

find /tmp /var/tmp -depth -mindepth 1 -type d -empty -print0 |
  xargs --null --no-run-if-empty rmdir

The second find command above uses `-depth' so it cleans out empty directories depth-first, hoping that the parents become empty and can be removed too. It uses `-mindepth' to avoid removing `/tmp' itself if it becomes totally empty.

Strange File Names

find can help you remove or rename a file with strange characters in its name. People are sometimes stymied by files whose names contain characters such as spaces, tabs, control characters, or characters with the high bit set. The simplest way to remove such files is:

rm -i some*pattern*that*matches*the*problem*file

rm asks you whether to remove each file matching the given pattern. If you are using an old shell, this approach might not work if the file name contains a character with the high bit set; the shell may strip it off. A more reliable way is:

find . -maxdepth 1 tests -ok rm '{}' \;

where tests uniquely identify the file. The `-maxdepth 1' option prevents find from wasting time searching for the file in any subdirectories; if there are no subdirectories, you may omit it. A good way to uniquely identify the problem file is to figure out its inode number; use

ls -i

Suppose you have a file whose name contains control characters, and you have found that its inode number is 12345. This command prompts you for whether to remove it:

find . -maxdepth 1 -inum 12345 -ok rm -f '{}' \;

If you don't want to be asked, perhaps because the file name may contain a strange character sequence that will mess up your screen when printed, then use `-exec' instead of `-ok'.

If you want to rename the file instead, you can use mv instead of rm:

find . -maxdepth 1 -inum 12345 -ok mv '{}' new-file-name \;

Fixing Permissions

Suppose you want to make sure that everyone can write to the directories in a certain directory tree. Here is a way to find directories lacking either user or group write permission (or both), and fix their permissions:

find . -type d -not -perm -ug=w | xargs chmod ug+w

You could also reverse the operations, if you want to make sure that directories do not have world write permission.

Classifying Files

If you want to classify a set of files into several groups based on different criteria, you can use the comma operator to perform multiple independent tests on the files. Here is an example:

find / -type d \( -perm -o=w -fprint allwrite , \
  -perm -o=x -fprint allexec \)

echo "Directories that can be written to by everyone:"
cat allwrite
echo ""
echo "Directories with search permissions for everyone:"
cat allexec

find has only to make one scan through the directory tree (which is one of the most time consuming parts of its work).

Go to the previous, next section.