質問

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 $@

他のヒント

xargs can only run a simple command. The && part gets interpreted by the shell which is not what you want. Just create a temporary script with the commands you want to run:

cat > script.sh
test -f "$1" && cp "$1" --target-directory=../folder/ --parents

Control-D

chmod u+x ./script.sh
echo $x | xargs -n1 ./script.sh

Also note that {} is not needed with -n1 because the parameter is used as the last word on a line.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top