I got a string with filenames I want to copy. However, only some of these files exist. My current script looks like this:
echo $x | xargs -n 1 test -f {} && cp --target-directory=../folder/ --parents
However, I always get a test: {}: binary operator expected
error.
How can I do that?
You need to supply the -i
flag to xargs
for it to substitute {}
for the filename.
However, you seem to expect xargs
to feed into the cp
, which it does not do. Maybe try something like
echo "$x" |
xargs -i sh -c 'test -f {} && cp --target-directory=../folder/ --parents {}'
(Notice also the use of double quotes with echo
. There are very few situations where you want a bare unquoted variable interpolation.)
To pass in many files at once, you can use a for
loop in the sh -c
:
echo "$x" |
xargs sh -c 'for f; do
test -f "$f" && continue
echo "$f"
done' _ |
xargs cp --parents --target-directory=".,/folder/"
The _
argument is because the first argument to sh -c
is used to populate $0
, not $@