重新格式化大量XML文件


11

我正在处理分散在整个嵌套目录结构中的大量XML文件。

我尝试了以下方法:

$ find . -name "*.xml" -type f | xargs -- xmllint --format

问题在于会在屏幕上生成格式化的XML输出,但不会更改文件。

如何更改此命令,以便更改实际文件内容?

Answers:


23

这可以通过find直接使用来完成-exec

find . -name "*.xml" -type f -exec xmllint --output '{}' --format '{}' \;

传递给-exec每个文件的文件将被调用一次,并将模板参数{}替换为当前文件名。在\;对find命令刚刚结束终止该行。

xargs在这种情况下,实际上并不需要使用,因为我们需要为xmllint每个文件调用一次,因为必须在同一调用中指定输入和输出文件名。

xargs如果从find通过管道传输到的命令一次在多个文件上运行并且该列表很长,则将需要此命令。在这种情况下,您无法执行此操作,因为您需要将单个文件名传递给的--output选项xmllint。如果不xargs处理大量文件,可能会导致“参数列表过长”错误。 xargs还支持带有以下-I选项的文件替换字符串:

find . -name "*.xml" -type f | xargs -I'{}' xmllint --output '{}' --format '{}'

find -exec上面的命令相同。如果您的文件夹中,如空格有奇怪的字符,你将需要使用-0的选项findxargs。但是使用xargswith -I意味着该选项-L 1意味着一次只能处理1个文件,因此您也可以直接使用findwith -exec


@manatwork感谢您的编辑-粘性手指; o)
Didster 2012年

我只是运行了它,似乎可以治疗了!非常感谢您迅速而简洁的回复!
哈里

2
“如果文件列表太大,这将失败”:不,它不会失败(它一次处理一个文件),实际上find … -exec是最直接的方法。
吉尔(Gilles)'所以

@吉尔斯好点!我已经相应更新了我的答案。
didster

1
之所以xmllint可行,是因为首先将完整的xml文档加载到内存中,然后再解析/写出。这允许文档就地处理。
Givenkoa

6

我通常使用间接层来解决这些问题。编写一个可以执行所需操作的shell脚本,然后调用它。我建议开始

#! /bin/sh
for file
do
   xmllint --format $file > $file.tmp && mv $file.tmp $file
done

手动在一个或两个文件上进行尝试,然后可以在xargs中替换它

find . -name "*.xml" -type f | xargs -- xmltidy.sh

如果将来我需要进行更复杂的操作,则这似乎是一种好方法。感谢您的回复。
哈里
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.