
У меня странная проблема с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
объединяет все строки в одну, а второй создает команду привязки). Когда я запускаю
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
который работает отлично.
Очевидно, я делаю что-то не так... Но что?
решение1
Есть несколько ошибок и ненужных сложностей:
- Двойной
xargs
вызов означает, что второй видит одну строку входных данных, поэтому{}
заменяется только один раз одной строкой, содержащей все совпадающие имена файлов, ноecho
не показывает эту разницу в выходных данных (сравнитеecho a b
сecho "a b"
). - Аргумент
-0
означает, что между входными аргументамиxargs
должен быть нулевой'\0'
символ ( ), но их нет; это также заставляет входные данные обрабатываться как один параметр. - Выводя только имя файла при выполнении условия, вы получаете по одному имени файла на строку, к которому можно напрямую обратиться
xargs
без необходимости использованияgrep
илиsed
. - К сожалению,
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'
опция позволяет команде работать, когда имена файлов содержат пробелы.
решение2
На странице руководства по xargs написано:
-Я заменяю-str
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).