It's really more like a variable. it "contains" the current file being processed by the
-exec command.
xargs uses pretty much the same syntax, although with
xargs you can redefine it to be any character string (using the
-I option) if you want.
Speaking of which,
-exec has a second command-ending style, which gives it xargs-style processing ability. With the usual "
;" ending,
find executes the command once for each file found. If you match 20 files, you get 20 executions. But if you replace it with "
+", it will gather multiple files together (as many as the system will allow) and run the command only once for the whole list.
Code:
find . -type f -exec mv -t targetdir '{}' '+'
This can often mean a great increase in speed and efficiency, but it comes with a couple of limitations. Since the '
{}' brackets now represent a
list of multiple files, they can now only come at the
end of the command, just in front of the '
+'. And the command you use must also be able to handle multiple file arguments in that fashion. e.g.
mv could not be used with it's usual syntax, since the last file in the list would be treated as the target directory. That's one reason why
gnu mv has added the
-t option to the command.
PS: Incidentally, the "safe" record separator in both
find and
xargs is the
null character, and that's generally used for safely transferring the list from one command to another through pipes. In find you use the
-print0 option (and relatives) for null-separated output, and
xargs will accept them as input delimiters with
-0.
The majority of other
gnu core commands also have some form of null separator option, but it varies by command, so check the man pages.
How can I find and deal with file names containing newlines, spaces or both?
http://mywiki.wooledge.org/BashFAQ/020