Окончательные аргументы для 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

Надеюсь, что это поможет кому-то в будущем.