
次の内容を含む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>