bash中的命令组合

时间:2011-07-23 06:36:55

标签: bash xargs

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

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为每个复合函数提供一个参数吗?

4 个答案:

答案 0 :(得分:4)

为什么不在shell中单独读取文件并处理每一行?即。

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

我希望这会有所帮助。

答案 1 :(得分:1)

使用GNU Parallel:

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

或者如果您想要包含提取网址:

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

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

答案 2 :(得分:0)

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

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

它只生成一个多命令行,为输入中的每个URL执行wget http://foo.xml.gz | gzip -d | xmlstartlet > $(basenname foo.xml.gz .gz).new;在评估结果命令之后

答案 3 :(得分:0)

如果xmlstarlet可以在stdin上运行而不必传递文件名,那么:

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

xargs选项-i表示您可以使用"{}"占位符来指示文件名的位置。使用-n 1表示xargs一次只能输入一行。