重新格式化大量 XML 文件

Har*_*rry 15 xml find xargs

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

我尝试了以下方法:

$ find . -name "*.xml" -type f | xargs -- xmllint --format
Run Code Online (Sandbox Code Playgroud)

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

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

did*_*ter 27

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

find . -name "*.xml" -type f -exec xmllint --output '{}' --format '{}' \;
Run Code Online (Sandbox Code Playgroud)

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

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

xargs如果通过管道传输到 find 的命令一次处理多个文件并且该列表很长,则将需要。你可以这样做,在这种情况下,你需要将单个文件名传递给--output的选项xmllint。如果没有xargs处理大量文件,最终可能会出现“参数列表太长”错误。 xargs还支持带有-I选项的文件替换字符串:

find . -name "*.xml" -type f | xargs -I'{}' xmllint --output '{}' --format '{}'
Run Code Online (Sandbox Code Playgroud)

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

  • “如果文件列表太大,这将失败”:不,它不会失败(一次处理一个文件),实际上`find ... -exec` 是最直接的方法。 (2认同)

Jul*_*ian 8

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

#! /bin/sh
for file
do
   xmllint --format $file > $file.tmp && mv $file.tmp $file
done
Run Code Online (Sandbox Code Playgroud)

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

find . -name "*.xml" -type f | xargs -- xmltidy.sh
Run Code Online (Sandbox Code Playgroud)