我正在尝试按字母顺序对看起来像这样的 XML 文件进行排序。这是一个更大的 bash 脚本的一部分,因此它需要在该脚本中工作:
<Module>
<Settings>
<Dimensions>
<Volume>13000</Volume>
<Width>5000</Width>
<Length>2000</Length>
</Dimensions>
<Stats>
<Mean>1.0</Mean>
<Max>3000</Max>
<Median>250</Median>
</Stats>
</Settings>
<Debug>
<Errors>
<Strike>0</Strike>
<Wag>1</Wag>
<MagicMan>0</MagicMan>
</Errors>
</Debug>
</Module>
Run Code Online (Sandbox Code Playgroud)
我希望最终结果看起来像这样,我只希望对最里面的标签进行排序:
<Module>
<Settings>
<Dimensions>
<Length>2000</Length>
<Volume>13000</Volume>
<Width>5000</Width>
</Dimensions>
<Stats>
<Max>3000</Max>
<Mean>1.0</Mean>
<Median>250</Median>
</Stats>
</Settings>
<Debug>
<Errors>
<MagicMan>0</MagicMan>
<Strike>0</Strike>
<Wag>1</Wag>
</Errors>
</Debug>
</Module>
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用这样的排序,其中 -t 按 > 分隔符排序,然后按第 4 列排序,这将在内部,但它不起作用。
sort -t'>' -k4 file > final.xml
Run Code Online (Sandbox Code Playgroud)
我得到时髦的输出,它用排序的内部标签对其他列进行排序。
任何帮助,将不胜感激
[在Kusalananda的慷慨协助下]
您可以使用做到这一点xq
从包装YQ(一个jq
杠杆的YAML / XML包装)jq
的排序功能:
$ xq -x 'getpath([paths(scalars)[0:-1]] | unique | .[])
|= (to_entries|sort_by(.key)|from_entries)' file.xml
<Module>
<Settings>
<Dimensions>
<Length>2000</Length>
<Volume>13000</Volume>
<Width>5000</Width>
</Dimensions>
<Stats>
<Max>3000</Max>
<Mean>1.0</Mean>
<Median>250</Median>
</Stats>
</Settings>
<Debug>
<Errors>
<MagicMan>0</MagicMan>
<Strike>0</Strike>
<Wag>1</Wag>
</Errors>
</Debug>
</Module>
Run Code Online (Sandbox Code Playgroud)
解释:
paths(scalars)
生成从根到叶的所有路径的列表,然后数组 slice[0,-1]
删除叶节点,从而生成到最深非叶节点的路径列表:
["Module","Settings","Dimensions"]
["Module","Settings","Dimensions"]
["Module","Settings","Dimensions"]
["Module","Settings","Stats"]
["Module","Settings","Stats"]
["Module","Settings","Stats"]
["Module","Debug","Errors"]
["Module","Debug","Errors"]
["Module","Debug","Errors"]
Run Code Online (Sandbox Code Playgroud)
[paths(scalars)[0:-1]] | unique | .[]
将列表放入一个数组中,以便它可以通过unique
. 迭代器.[]
将其转回列表:
["Module","Debug","Errors"]
["Module","Settings","Dimensions"]
["Module","Settings","Stats"]
Run Code Online (Sandbox Code Playgroud)
getpath()
将去重列表转换为底层对象,其内容可以使用|=
update-assign 运算符进行排序和更新
该-x
选项告诉xq
将结果转换回 XML 而不是将其保留为 JSON。
请注意,如果键不唯一,则 whilesort
在这里代替sort_by(.key)
前者隐式按值和键排序。