无法使 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主题标签中包含单词 DATA 的所有 pdf,
  • 指示-p exifprintformatexiftool打印文件名,
  • 仅选择grep带有 pdf 的行,
  • 删除sed空格,
  • xarg当我运行

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

我明白了

pdftk 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf cat 输出活页夹1.pdf

效果非常好。

显然,我做错了……但是是什么呢?

答案1

有几个地方是错误的,而且有不必要的复杂性:-

  1. 双重xargs调用意味着第二个调用看到单行输入,因此{}只用包含所有匹配文件名的单个字符串替换一次,但echo不会在输出中显示这种差异(echo a b与比较echo "a b")。
  2. -0参数意味着xargs需要在输入参数之间有一个空字符('\0'),但是没有;这也强制将输入视为单个参数。
  3. 通过在条件匹配时仅输出文件名,您将获得每行一个文件名,可以直接通过管道传输而xargs无需grepsed
  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'选项可使命令起作用。

答案2

xargs 的手册页显示:

-I 替换-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 删除所有空格)。

相关内容