Окончательные аргументы для xargs
Я хочу сделать что-то похожее на это:
find . -type f | xargs cp dest_dir
Но xargs
будет использовать dest_dir
как начальный аргумент, а не как окончательный аргумент. Я хотел бы знать:
- Можно ли указать конечные аргументы для
xargs
?
- Любая другая альтернатива для достижения того же результата?
ИЗМЕНИТЬ
Возможная, но громоздкая альтернатива такова:
find . -type f | while read f ; do echo cp $f dest_dir ; done
Мне это не нравится, потому что будут запущены десятки процессов cp
.
Ответы
Ответ 1
Параметр -I
заменяет вхождения replace-str
в начальных аргументах с именами, считанными со стандартного ввода.
Например:
find . -type f | xargs -I file cp file dest_dir
Необходимо решить вашу проблему.
Подробнее в следующем учебнике:
http://www.cyberciti.biz/faq/linux-unix-bsd-xargs-construct-argument-lists-utility/
В частности, часть о {}
в качестве маркера списка аргументов
Ответ 2
Обычно вам не нужно использовать xargs
(например, find . -type f -exec cp {} dest_dir +
). Но на всякий случай вы...
Просто сохраните ниже script в $PATH
и используйте его как:
find . -type f | xargs final-args dest_dir -- cp
Script:
#!/bin/bash
# Usage: final-args 4 5 6 -- echo 1 2 3
final=()
for arg
do
shift
if [[ "$arg" = "--" ]]
then
break
fi
final+=("$arg")
done
exec "[email protected]" "${final[@]}"
Ответ 3
Как альтернативное решение, используйте -t
, когда команда его поддерживает. cp
и mv
.
find -type f -print0 | xargs -0 cp -t dest_dir --
find -type f -exec cp -t dest_dir -- {} +
Как отмечено o11c, использование xargs
в этом случае не требуется.
Также обратите внимание, что в первом примере я использовал -print0
и -0
. Использование '\0'
в качестве разделителя позволяет избежать проблем с именами файлов, имеющих новые строки с ними.
Все здесь также не предлагали по крайней мере использовать -d '\n'
. xargs
разбивает пробелы (а не только символы новой строки), если они не указаны.
find -type f | xargs -d '\n' cp -t dest_dir --
Ответ 4
Я пытался добиться чего-то немного другого, используя xargs и pdfunite, и запуск нескольких экземпляров pdfunite не сократил его для меня.
Я старался:
$ ls -v *.pdf | xargs pdfunite <files> all-files.pdf
с all-files.pdf
является последним аргументом для pdfunite. Но xargs
с -I
не дал мне того, что я хотел:
$ ls -v *.pdf | xargs -I {} pdfunite {} all-files.pdf
Это только что дало мне результат, который all-files.pdf
был последним выходным файлом ls
. И это потому, что были запущены несколько экземпляров pdfunite.
Я, наконец, просто отказался от xargs
и пошел со следующей простой конструкцией, которая была достаточной для моих целей:
$ pdfunite `ls -v *.pdf` all-files.pdf
Надеюсь, что это поможет кому-то в будущем.