I want to use find to locate files, then copy those to a directory, so I tried:
find . -name '*.png' -exec cp {} /tmp/dest +
However, this fails with
find: missing argument to `-exec'
When I replace the +
by a ;
it works, but invokes cp for every file individually. How can I add a trailing argument (such as a destination directory) when using the +
form of -exec
?
Of course, in this case I can work around the apparent limitation by using cp -t
(such as indicated in this post on Stack Overflow, but that solution is specific to cp
. Instead, I might be using rsync, scp, or some other tool. Is there a general way to add arguments between {}
and +
in find -exec
?
Best Answer
No, if you're using
-exec ... {} +
, there may be nothing between{}
and+
apart from whitespace. There is no way around that.From the POSIX standard specification of the
find
command:A more generic solution would possibly be
Here, an inline
sh -c
script is executed with batches of arguments fromfind
. Inside the inline script,"$@"
will be the list of passed arguments (individually quoted), which allows us to place them as we want them on thecp
command line.This allows us to use non-GNU
cp
(on e.g. macOS or other BSD systems, where there is no-t
option) or any other utility where one may want to add other arguments to the end of the list of pathnames coming fromfind
.Related:
Nobody asked for this, but anyway...
With the destination directory in a variable,
destdir
:Note that the
destdir
in the shell callingfind
is a separate variable to thedestdir
in thesh -c
script.Or, with
bash
:This is "slicing" the
"$@"
list to rearrange it appropriately for thecp
command line, without extracting$1
, the destination directory pathname, into a separate variable.