通过检查上一行和下一行来替换一行内容

Mr.*_*.EU 5 shell awk sed

我试图通过检查前一行和下一行来替换内容。如下所示。

<Info>
<pInfo>"eth0"</pInfo>
<IpAdd>192.168.1.2</IpAdd>
<port>1123</port>
</Info>
<Info>
<pInfo>"eth1"</pInfo>
<IpAdd>192.168.1.22</IpAdd>
<port>6789</port>
</Info>
<User>
<avl>"Name"</avl>
<IpAdd>192.168.1.2</IpAdd>
<port>1123</port>
</User>
Run Code Online (Sandbox Code Playgroud)

替换<IpAdd>any IP address</IpAdd><IpAdd>111.111.111.111</IpAdd>下一行所在的内容<port>1123</port>,并且它应该位于<Info><pInfo>"eth0"</pInfo>部分下。

我尝试过的:

sed -E "/<Info>/{n;/<pInfo>/{n;s@<IpAdd>.*<([^\n]*\n[^\n]*<port>1123</port>)@<IpAdd>111.111.111.111<@}}" test.txt
Run Code Online (Sandbox Code Playgroud)

想要替换端口 1123 上面的行。如果我删除([^\n]*\n[^\n]*<port>1123</port>),那么它会替换 Info 下的两个 ip。

<Info>
<pInfo>"eth0"</pInfo>
<IpAdd>111.111.111.111</IpAdd>
<port>1123</port>
</Info>
<Info>
<pInfo>"eth1"</pInfo>
<IpAdd>111.111.111.111</IpAdd>
<port>6789</port>
</Info>
<User>
<avl>"Name"</avl>
<IpAdd>192.168.1.2</IpAdd>
<port>1123</port>
</User>
Run Code Online (Sandbox Code Playgroud)

预计:

<Info>
<pInfo>"eth0"</pInfo>
<IpAdd>111.111.111.111</IpAdd>
<port>1123</port>
</Info>
<Info>
<pInfo>"eth1"</pInfo>
<IpAdd>192.168.1.22</IpAdd>
<port>6789</port>
</Info>
<User>
<avl>"Name"</avl>
<IpAdd>192.168.1.2</IpAdd>
<port>1123</port>
</User>
Run Code Online (Sandbox Code Playgroud)

pot*_*ong 2

这可能对你有用(GNU sed):

sed -E '/<Info>/{:a;N;/<\/Info>$/!ba
        s/(<IpAdd>).*(<\/IpAdd>\n<port>1123<\/port>)/\1111.111.111.111\2/}' file
Run Code Online (Sandbox Code Playgroud)

<Info>收集和之间的行</Info>,然后匹配集合中以 开头<IpAddr>和结尾的两行1123</port>,并用新地址替换旧地址。