2013-05-27 4 views
0

У меня есть строка с именами файлов, которые я хочу скопировать. Однако существуют только некоторые из этих файлов. Мой текущий сценарий выглядит следующим образом:xargs copy, если файл существует

echo $x | xargs -n 1 test -f {} && cp --target-directory=../folder/ --parents 

Однако, я всегда получаю ошибку test: {}: binary operator expected.

Как я могу это сделать?

ответ

3

Вам необходимо поставить флаг -i на номер xargs, чтобы он мог заменить {} на имя файла.

Однако, похоже, вы ожидаете, что xargs подаст в cp, которого он не делает. Может быть, попробовать что-то вроде

echo "$x" | 
xargs -i sh -c 'test -f {} && cp --target-directory=../folder/ --parents {}' 

(Обратите также внимание на использование двойных кавычек с echo. Есть очень мало ситуаций, когда вы хотите голую без кавычек переменной интерполяции.)

+0

большое решение, спасибо. Мне интересно, почему вы не используете аргумент «-n 1». Из того, что я думал, без него xargs собирается вводить несколько аргументов за раз, предоставляя 'test -f' бесполезным. – Zulakis

+0

С '-i' обязательно подразумевается' -n 1'. Особенно с несколькими '{}' заполнителями, 'xargs' не может проходить более чем по одному файлу за раз (или синтаксис для указания одного из многих возможных вариантов поведения должен быть сбивающим с толку). – tripleee

+0

Ах ладно, спасибо. Я не мог найти это в 'man xargs':/ – Zulakis

2

xargs может выполнять только простую команду. Часть && интерпретируется оболочкой, которая не является тем, что вы хотите. Просто создайте временный скрипт с командами вы хотите запустить:

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 

отметить также, что {} не требуется с -n1, поскольку параметр используется в качестве последнего слова на линии.

Смежные вопросы