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

 exiftool -p exifprintformat  -if '$Subject =~/DATA/i' -q  *.pdf |grep pdf |sed 's/ //g'|xargs|xargs -0 -I % pdftk % cat output binder1.pdf  

и выход

Ошибка: невозможно найти файл. Ошибка: не удалось открыть файл PDF: 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf

  • exiftool выбирает все файлы PDF, содержащие слово DATA в теге темы,
  • -p exifprintformat указывает exiftool печатать только имя файла,
  • grep выделяет только строки с pdf,
  • sed удаляет пробелы,
  • Первый xarg превращает все строки в одну строку, а второй создает команду bind), когда я запускаю

exiftool -p exifprintformat -if '$ Subject = ~/DATA/i' -q * .pdf | grep pdf | sed 's/ // g' | xargs | xargs -I {} echo pdftk {} cat output binder1.pdf

я получил

pdftk 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf cat output binder1.pdf

который работает отлично.

Очевидно, я делаю что-то не так ...Но что?

2 ответа2

0

Страница man для xargs гласит:

-Я заменяю-ул

  Replace occurrences of replace-str in the initial-arguments with
  names read from standard input.   Also, unquoted blanks do not
  terminate input items; instead the separator is the newline
  character.  Implies -x and -L 1.

Другими словами, вы в конечном итоге с одним аргументом под названием " 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf "

Я предлагаю отказаться от xargs и переупорядочить вашу команду примерно так:

pdftk $(exiftool -p exifprintformat -if '$Subject =~/DATA/i' -q *.pdf |grep pdf |sed 's/ //g'| tr '\n' ' ') cat output binder1.pdf

Все это предполагает, что у вас нет пробелов в именах файлов (безопасное предположение, так как вы все равно удалили все пробелы с помощью sed).

0

Есть несколько неправильных вещей и ненужная сложность:

  1. Вызов double xargs означает, что секунда видит одну строку ввода, поэтому {} заменяется один раз одной строкой, содержащей все совпадающие имена файлов, но echo не показывает эту разницу в выводе (сравните echo a b с echo "a b").
  2. Аргумент -0 означает, что xargs необходим нулевой символ ('\0') между входными аргументами, а их нет; это также заставляет входные данные обрабатываться как один параметр.
  3. Выводя только имя файла, когда условие соответствует, вы получаете одно имя файла на строку, которое может быть передано напрямую в xargs без необходимости использования grep или sed .
  4. К сожалению, xargs -I одну команду на строку ввода, и нет возможности добавить параметры трейлинга, но есть простой способ: добавить параметры трейлинга во входной поток.

Это упрощенная команда с добавленными конечными параметрами (я тестировал с другим условием -if , не имея PDF-файлов, которые соответствуют):

{ exiftool -p '${FileName}' -if '$Subject =~/DATA/i' -q *.pdf; \
  echo -e "cat\noutput\nbinder1.pdf"; } | xargs -d'\n' pdftk

Параметр xargs -d'\n' заставляет команду работать, когда в именах файлов есть пробелы.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .