sed/awk 字符串替换为换行符和制表符

sed/awk 字符串替换为换行符和制表符

我有一个包含以下内容的 XML 文件:

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

目标是在一个命令中修改<ipaddr>192.168.1.1</ipaddr>to<ipaddr>192.168.1.125</ipaddr><subnet>24</subnet>to 。<subnet>25</subnet>我不想更改文件内的任何其他子网标记。

我遇到的问题是后面有一个换行符</ipaddr>,前面有两个制表符<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

假设您要更改一行上的 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>

相关内容