Previous | Table of Contents | Next |
If you specify more than one option, the file must match all options to be displayed:
find / -name alpha -size +50 -mtime -3 -print
Here find displays files only when all the following are true:
You can specify a logical or condition using -o:
find / \( -size +50 -o -mtime -3 \) -print
Notice the use of the escaped parentheses to group the either and or options. This finds files that either have size greater than 50 blocks or were last modified fewer than 3 days ago.
You can use the ! sign to select files that do not match the given option:
find /dev ! \( -type b -o -type c -o type d \) -print
This locates all files in the /dev directory and its subdirectories that are not block special device files, character special device files, or directories. This is a useful command to locate device names that users have misspelled, which leaves a regular file in /dev that can waste a large amount of disk space.
-print is an action that tells find to display the pathnames of all files that match the options given before -print. If you put the -print action before other options in the command line, those options are not used in the selection process:
find / -size -20 -print -mtime +30
This command prints all files that contain fewer than 20 blocks. The -mtime option is ignored because it comes after the -print action on the command line.
If no action is specified on the command line, -print is usually done by default. On older versions of UNIX, however, you must remember to include -print specifically, or no output is generated.
-exec is an action that lets you specify a UNIX command to run on each of the files that match the options given:
find / -name alpha -exec chmod a+r {} \;
Following -exec, you should specify a complete UNIX command and put {} where the filename will be inserted. Add \; at the end of the command to complete the required syntax. In the previous example, chmod runs on every file named alpha so that everyone can read the file.
find / -name core -exec rm -f {} \;
This example finds all files on the system named core and executes the rm command to delete them. The -f option to rm is specified so that rm does not ask for confirmation if you dont own the file and dont have write permission to the file. This is a useful command for root to run periodically because, if a process aborts, it might leave a debugging file named core in the current directory. After a while, these core files, which are not small, can collectively consume an unreasonable amount of disk space. This find command restores that disk space by finding and deleting those core files.
Note:
If you have thousands of files to process, xargs (covered in the next section) is more efficient than -exec. For example,find / -name core -print | xargs rm -fThis command also deletes all core files much more quickly and with less overhead than the -exec option, which calls rm once for each file.
xargs is a command that accepts a list of words from standard input and provides those words as arguments to a given command:
cat filelist | xargs rm
You cannot pipe the output of cat directly to rm because rm does not look for filenames on standard input. xargs reads the files being passed by cat and builds up a command line beginning with rm and ending with the filenames. If there are a large number of files, xargs runs the rm command multiple times, deleting some of the files each time. You can specify how many arguments from standard input to build up on the command line with the -n option:
cat filelist | xargs -n 20 rm
-n 20 says to put only 20 arguments on each command line, so you delete only 20 files at a time. Here is a different example to give you more insight into how xargs works:
$ ls acme report16 report3 report34 report527 $ ls | xargs -n 2 echo === === acme report16 === report3 report34 === report527 $
The first ls command shows us that there are only five files in the current directory. (These five can be regular files or directories; it does not matter for this example.) Next you pipe the output of ls to xargs, which composes and executes this command (the first of several):
echo === acme report16
The command begins with echo === because these are the arguments given to the xargs command. The command then contains two filenames read from standard input. -n 2 tells xargs to add only two words from standard input to each echo command. I added === as the first echo argument so you can visually find the output from each separate echo command. You can see that xargs called echo three times to process all the standard input.
xargs can be used to solve this problem:
$ rm abc* rm: arg list too long
The current directory contained too many filenames starting with abc, and the command buffer overflowed, so an error message was printed, and none of the files were deleted. xargs can solve this buffer overflow problem:
ls | grep '^abc' | xargs -n 20 rm
Here you use grep (covered in Chapter 15, Text Filters) and regular expressions (covered in Chapter 16, Filtering Text Using Regular Expressions) to filter the output of ls passing only filenames that begin with abc. xargs allows rm to operate on those files and delete them, no matter how many there are.
Previous | Table of Contents | Next |