子xmlタグを条件付きで削除するシェルスクリプト

子xmlタグを条件付きで削除するシェルスクリプト

次の内容を含むxmlファイルがあります。

<contracts>
    <clients>
        <client>
            <name>Nicol</name>
            <clientRef>123</clientRef>
        </client>
        <client>
            <name>Basil</name>
            <clientRef>8234</clientRef>
        </client>
    </clients>
    <entries>
        <entry>
            <regCode>BCG</regCode>
            <clientRef>63352</clientRef>
        </entry>
        <entry>
            <regCode>TYD</regCode>
            <clientRef>3242</clientRef>
        </entry>
    </entries>
</contracts>  

xml タグ "clientRef" は、クライアントとエントリのセクションにあります。ただし、クライアントセクションからclientRefタグを削除するだけです。

希望の出力は次のとおりです。

<contracts>
    <clients>
        <client>
            <name>Nicol</name>
        </client>
        <client>
            <name>Basil</name>
        </client>
    </clients>
    <entries>
        <entry>
            <regCode>BCG</regCode>
            <clientRef>63352</clientRef>
        </entry>
        <entry>
            <regCode>TYD</regCode>
            <clientRef>3242</clientRef>
        </entry>
    </entries>
</contracts>

私はshellとsedコマンドを初めて使用します。シェルスクリプトを使用してclientRefタグを削除する方法は?

ベストアンサー1

可能ですが、とてもとても悪い考えです。sed正規表現ベースのツールを使用してXMLまたはHTMLを解析します。これは簡単な場合には機能しますが、正しくすることは困難です。専門家にも、少し複雑な状況の場合。したがって、次のXMLパーサーを使用してくださいxmlstarlet(オペレーティングシステムリポジトリからインストール可能である必要があります)。

$ xmlstarlet ed -d '//client/clientRef' file.xml  
<?xml version="1.0"?>
<contracts>
  <clients>
    <client>
      <name>Nicol</name>
    </client>
    <client>
      <name>Basil</name>
    </client>
  </clients>
  <entries>
    <entry>
      <regCode>BCG</regCode>
      <clientRef>63352</clientRef>
    </entry>
    <entry>
      <regCode>TYD</regCode>
      <clientRef>3242</clientRef>
    </entry>
  </entries>
</contracts>

これはed「このファイルを編集する」という意味で、これは以下の項目を-d '//client/clientRef'「削除」することを意味します。clientRefclient


この特別なケースでは、単純なテキスト解析ツールを使用することもできますので、例を示します。ただし、より複雑な作業では、これを行うのではなく、小さな変更でも中断される可能性があることに注意してください。入力データ:

$ awk '{ 
        if(/<clients>/){a=1}
        else if(/<\/clients>/){a=0} 
        if(/<clientRef>/ && a){ next}
       }1;' file.xml 
<contracts>
    <clients>
        <client>
            <name>Nicol</name>
        </client>
        <client>
            <name>Basil</name>
        </client>
    </clients>
    <entries>
        <entry>
            <regCode>BCG</regCode>
            <clientRef>63352</clientRef>
        </entry>
        <entry>
            <regCode>TYD</regCode>
            <clientRef>3242</clientRef>
        </entry>
    </entries>
</contracts>  

おすすめ記事