UNIXでは、Bashスクリプトを使用してXMLファイルをソートしますか?

UNIXでは、Bashスクリプトを使用してXMLファイルをソートしますか?

以下に示す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>

私は最終結果が次のようになりたいです。最も内側のタグだけがソートされるようにしたいです。

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

-tが>区切り記号で並べ替えてから、内側の4列目に4を並べ替えるなどの並べ替えを使用しようとしましたが、機能しません。

sort -t'>' -k4 file > final.xml

ソートされた内部ラベルを使用して、別の列をソートする奇妙な出力を取得します。

どんな助けでも大変感謝します。

ベストアンサー1

[惜しみない助けで先行は達成するのが難しい]

xq次のラッパーを使用してこれを実行できます。yq(YAML / XMLラッパー)はソート機能をjq利用します。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>

説明する:

  • paths(scalars)ルートからリーフまでのすべてのルートのリストを作成し、アレイスライスからリーフ[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"]
    
  • [paths(scalars)[0:-1]] | unique | .[]として重複した項目を削除できるように、リストを配列に配置しますunique。イテレータは.[]それをリストとして返します。

    ["Module","Debug","Errors"]
    ["Module","Settings","Dimensions"]
    ["Module","Settings","Stats"]
    
  • getpath()|=更新割り当て演算子を使用して、内容を並べ替えて更新できる基本オブジェクトに重複排除リストを変換します。

この-xオプションは、xq結果をJSONのままにせずに再びXMLに変換するように指示します。

ここでは、前者をsort置き換えますが、キーが一意でない場合は、値とキーに基づいて暗黙的に並べ替えます。sort_by(.key)

おすすめ記事