【问题标题】:Command composition in bashbash 中的命令组合
【发布时间】:2011-07-24 08:45:40
【问题描述】:

所以我有一个由另一个命令输出的文件列表,它看起来像这样:

http://somewhere.com/foo1.xml.gz
http://somewhere.com/foo2.xml.gz
...

我需要通过 xmlstarlet 在每个文件中运行 XML,所以我正在做 ... | xargs gzip -d | xmlstarlet ...,除了我希望为进入 gzip 的每一行调用一次 xmlstarlet,而不是在所有相互附加的 xml 文档上.是否可以compose 'gzip -d' 'xmlstarlet ...',以便 xargs 为其每个复合函数提供一个参数?

【问题讨论】:

  • 当有管道时,你不能在 xargs 中这样做......你可以,但是以一种非常笨拙的方式......改用 shellter answer 之类的东西。

标签: bash xargs


【解决方案1】:

为什么不读取文件并在 shell 中分别处理每一行?即

fileList=/path/to/my/xmlFileList.txt
cat ${fileList} \
| while read fName ; do
   gzip -d ${fName} | xmlstartlet > ${fName}.new
done 

我希望这会有所帮助。

【讨论】:

  • 正是我要建议 +1。
  • 不要虐待猫...在阅读 fName 时使用;做 ...;完成
  • 是的,我知道这一点,但使用 cat 因为对于某些 shell,我似乎记得 ... done < ${fName}(有一个变量保存 inputFile)不可靠(我认为,或者可能是别的东西;-)。谢谢提醒。
【解决方案2】:

虽然正确答案是庇护所建议的答案 (+1),但这里有一个单行“divertimento”,前提是输入是 Andrey 提出的(command 生成网址列表):-)

~$ eval $(command | awk '{a=a "wget -O - "$0" | gzip -d | xmlstartlet > $(basename "$0" .gz ).new; " } END {print a}')

它只是生成一个多命令行,为输入中的每个 url 执行wget @987654321@ | gzip -d | xmlstartlet > $(basenname foo.xml.gz .gz).new;在计算结果命令后

【讨论】:

    【解决方案3】:

    使用 GNU 并行:

    cat filelist | parallel 'zcat {} | xmlstarlet >{.}.out'
    

    或者如果你想包含 url 的获取:

    cat urls | parallel 'wget -O - {} | zcat | xmlstarlet >{.}.out'
    

    它易于阅读,并且您可以获得每个 CPU 并行运行的工作的额外好处。观看介绍视频以了解更多信息:http://www.youtube.com/watch?v=OpaiGYxkSuQ

    【讨论】:

      【解决方案4】:

      如果 xmlstarlet 可以在标准输入上操作而不必传递文件名,那么:

      some command | xargs -i -n1 sh -c 'zcat "{}" | xmlstarlet options ...'
      

      xargs 选项-i 意味着您可以使用"{}" 占位符来指示文件名的位置。使用 -n 1 指示 xargs 一次只能从其输入中提取一行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-06
        • 2021-07-20
        • 2015-07-23
        • 1970-01-01
        • 2013-06-02
        • 1970-01-01
        • 2019-10-13
        相关资源
        最近更新 更多