改行文字とタブでsed / awk文字列を置き換える

改行文字とタブでsed / awk文字列を置き換える

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

<ipaddr>192.168.1.1</ipaddr>
    <subnet>24</subnet>

目的は、1つのコマンドで<ipaddr>192.168.1.1</ipaddr>to<ipaddr>192.168.1.125</ipaddr>とtoを変更することです<subnet>24</subnet><subnet>25</subnet>ファイル内の他のサブネットタグを変更したくありません。

私が経験している問題は、後ろに改行文字があり、</ipaddr>その前に2つのタブ文字があることです<subnet>

私はこれを試しましたが、awk '{gsub (/<ipaddr>192.168.1.1<\/ipaddr>\n<subnet>24<\/subnet>/, "<ipaddr>192.168.1.125<\/ipaddr>\n\t\t<subnet>25<\/subnet>")}' config.xml うまくいきません。

誰かが私に正しい方向を教えてもらえますか?

答え1

1行ではIPを変更し、次の行ではサブネットを変更するとします。

 sed -E '/(192.168.1.)1/{s//\1125/; n; s/>24</>25</}' infile

IPは変更されますが、サブネットは変更されない場合、エラーは報告されません。あなたの説明によると、これはあなたが望むようです。

答え2

これはやや不完全な仕様です。私たちは何を探していますか?一般的なパターンがありますか?正確なIPアドレスとサブネットは何ですか?それでは試してみてください。

$ sed -r '/(192.168.1.)1/{s//\1125/; N; s/24/25/}' file
<ipaddr>192.168.1.125</ipaddr>
          <subnet>25</subnet>

答え3

データが次のように正しい形式のXML文書であるとします。

<?xml version="1.0"?>
<root>
  <ipaddr>192.168.1.2</ipaddr>
  <subnet>24</subnet>
  <ipaddr>192.168.1.1</ipaddr>
  <subnet>24</subnet>
</root>

次のXMLStarletコマンドは、ipaddr現在の値が192.168.1.1あり、最初のsubnet兄弟が24のノードを見つけて、ipaddrノードの値をに変更します192.168.1.125。次に、同様の操作を実行してsubnetノード値を25に変更し、ノードの新しい値を使用してipaddr場所を指定します。

xmlstarlet ed \
    -u '//ipaddr[. = "192.168.1.1" and following-sibling::subnet[1] = "24"]' -v '192.168.1.125' \
    -u '//subnet[. = "24" and preceding-sibling::ipaddr[1] = "192.168.1.125"]' -v 25 file.xml

結果は次のとおりです。

<?xml version="1.0"?>
<root>
  <ipaddr>192.168.1.2</ipaddr>
  <subnet>24</subnet>
  <ipaddr>192.168.1.125</ipaddr>
  <subnet>25</subnet>
</root>

ipaddrそして、subnetノードが同じ親ノードの子である場合、以下のようにコマンドははるかに簡単でエラーの可能性が低くなります。

<?xml version="1.0"?>
<root>
  <host name="hostA">
    <ipaddr>192.168.1.2</ipaddr>
    <subnet>24</subnet>
  </host>
  <host name="hostB">
    <ipaddr>192.168.1.1</ipaddr>
    <subnet>24</subnet>
  </host>
</root>

hostその後、次のようにノード名を選択できます。

xmlstarlet ed \
    -u '//host[@name="hostB"]/ipaddr' -v '192.168.1.125' \
    -u '//host[@name="hostB"]/subnet' -v '25' file.xml

生産

<?xml version="1.0"?>
<root>
  <host name="hostA">
    <ipaddr>192.168.1.2</ipaddr>
    <subnet>24</subnet>
  </host>
  <host name="hostB">
    <ipaddr>192.168.1.125</ipaddr>
    <subnet>25</subnet>
  </host>
</root>

関連情報