所以我有一个由另一个命令输出的文件列表,它看起来像这样:
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为每个复合函数提供一个参数吗?
答案 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一次只能输入一行。