2

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

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

4 回答 4

4

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

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

我希望这有帮助。

于 2011-07-23T07:10:03.887 回答
1

使用 GNU 并行:

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

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

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

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

于 2011-07-24T00:39:11.130 回答
1

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

~$ 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

于 2011-07-23T14:15:17.847 回答
0

如果 xmlstarlet 可以对标准输入进行操作,而不必向其传递文件名,则:

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

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

于 2011-07-23T17:39:21.660 回答