find: Multiple Files
1
1 3.3.2 Multiple Files
1 --------------------
1
1 Sometimes you need to process files one at a time. But usually this is
1 not necessary, and, it is faster to run a command on as many files as
1 possible at a time, rather than once per file. Doing this saves on the
1 time it takes to start up the command each time.
1
1 The '-execdir' and '-exec' actions have variants that build command
1 lines containing as many matched files as possible.
1
1 -- Action: -execdir command {} +
1 This works as for '-execdir command ;', except that the result is
1 always true, and the '{}' at the end of the command is expanded to
1 a list of names of matching files. This expansion is done in such
1 a way as to avoid exceeding the maximum command line length
1 available on the system. Only one '{}' is allowed within the
1 command, and it must appear at the end, immediately before the '+'.
1 A '+' appearing in any position other than immediately after '{}'
1 is not considered to be special (that is, it does not terminate the
1 command).
1
1 -- Action: -exec command {} +
1 This insecure variant of the '-execdir' action is specified by
1 POSIX. The main difference is that the command is executed in the
1 directory from which 'find' was invoked, meaning that '{}' is
1 expanded to a relative path starting with the name of one of the
1 starting directories, rather than just the basename of the matched
1 file. The result is always true.
1
1 Before 'find' exits, any partially-built command lines are executed.
1 This happens even if the exit was caused by the '-quit' action.
1 However, some types of error (for example not being able to invoke
1 'stat()' on the current directory) can cause an immediate fatal exit.
1 In this situation, any partially-built command lines will not be invoked
1 (this prevents possible infinite loops).
1
1 At first sight, it looks like the list of filenames to be processed
1 can only be at the end of the command line, and that this might be a
1 problem for some commands ('cp' and 'rsync' for example).
1
1 However, there is a slightly obscure but powerful workaround for this
1 problem which takes advantage of the behaviour of 'sh -c':
1
1 find startpoint -tests ... -exec sh -c 'scp "$@" remote:/dest' sh {} +
1
1 In the example above, the filenames we want to work on need to occur
1 on the 'scp' command line before the name of the destination. We use
1 the shell to invoke the command 'scp "$@" remote:/dest' and the shell
1 expands '"$@"' to the list of filenames we want to process.
1
1 Another, but less secure, way to run a command on more than one file
1 at once, is to use the 'xargs' command, which is invoked like this:
1
1 xargs [OPTION...] [COMMAND [INITIAL-ARGUMENTS]]
1
1 'xargs' normally reads arguments from the standard input. These
1 arguments are delimited by blanks (which can be protected with double or
1 single quotes or a backslash) or newlines. It executes the COMMAND (the
1 default is 'echo') one or more times with any INITIAL-ARGUMENTS followed
1 by arguments read from standard input. Blank lines on the standard
1 input are ignored. If the '-L' option is in use, trailing blanks
1 indicate that 'xargs' should consider the following line to be part of
1 this one.
1
1 Instead of blank-delimited names, it is safer to use 'find -print0'
1 or 'find -fprint0' and process the output by giving the '-0' or '--null'
1 option to GNU 'xargs', GNU 'tar', GNU 'cpio', or 'perl'. The 'locate'
1 command also has a '-0' or '--null' option which does the same thing.
1
1 You can use shell command substitution (backquotes) to process a list
1 of arguments, like this:
1
1 grep -l sprintf `find $HOME -name '*.c' -print`
1
1 However, that method produces an error if the length of the '.c' file
1 names exceeds the operating system's command line length limit. 'xargs'
1 avoids that problem by running the command as many times as necessary
1 without exceeding the limit:
1
1 find $HOME -name '*.c' -print | xargs grep -l sprintf
1
1 However, if the command needs to have its standard input be a
1 terminal ('less', for example), you have to use the shell command
1 substitution method or use the '--arg-file' option of 'xargs'.
1
1 The 'xargs' command will process all its input, building command
1 lines and executing them, unless one of the commands exits with a status
1 of 255 (this will cause xargs to issue an error message and stop) or it
1 reads a line contains the end of file string specified with the '--eof'
1 option.
1
Menu