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:
-exec utility_name [argument ...] ;
-exec utility_name [argument ...] {} +
The end of the primary expression shall be punctuated by a <semicolon>
or by a <plus-sign>
. Only a <plus-sign>
that immediately follows an argument containing only the two characters {}
shall punctuate the end of the primary expression. Other uses of the <plus-sign>
shall not be treated as special.
A more generic solution would possibly be
find ... -exec sh -c 'cp "$@" /tmp/dest' sh {} +
Here, an inline sh -c
script is executed with batches of arguments from find
. Inside the inline script, "$@"
will be the list of passed arguments (individually quoted), which allows us to place them as we want them on the cp
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 from find
.
Related:
Nobody asked for this, but anyway...
With the destination directory in a variable, destdir
:
destdir=/tmp/dest
find ... -exec sh -c 'destdir=$1; shift; cp "$@" "$destdir"' sh "$destdir" {} +
Note that the destdir
in the shell calling find
is a separate variable to the destdir
in the sh -c
script.
Or, with bash
:
destdir=/tmp/dest
find ... -exec bash -c 'cp "${@:2}" "$1"' bash "$destdir" {} +
This is "slicing" the "$@"
list to rearrange it appropriately for the cp
command line, without extracting $1
, the destination directory pathname, into a separate variable.
cp -t /tmp/dest {} +
– nezabudka Oct 21 '20 at 12:29cp
but may not work for other applications where I may need a similar syntax. – gerrit Oct 21 '20 at 12:31-exec ... \;
usage of-exec
, and does not consider-exec ... {} +
, which would not execute the utility more than once per batch, just likexargs
would. This question is about the-exec ... {} +
usage and syntax specifically. – Kusalananda Oct 21 '20 at 12:38mv
andcp
were historical anomalies that took a directory last, and were fixed so they worked with xargs. I can't offhand think of any other such anomalies. – Paul_Pedant Oct 21 '20 at 13:55rsync
rather than cp? For example,rsync src1 src2 src3 src4 user@host:dest/
?rsync --help | grep target
comes up empty. Same forscp
. – gerrit Oct 21 '20 at 15:57find -print0
and pipe them intorsync --files-from=- --from0
. They don't appear on the command line at all, so this fixes both the args order and the max-args limit. I found this athttps://unix.stackexchange.com/questions/87018/find-and-rsync
. – Paul_Pedant Oct 21 '20 at 16:25( cd /src && tar czf - . ) | ssh usr@host '( cd /dst && tar xzf - )'
. – Paul_Pedant Oct 21 '20 at 16:50