【问题标题】:sed / awk match second occurrence of regex in a file, and replace whole linesed / awk 匹配文件中第二次出现的正则表达式,并替换整行
【发布时间】:2022-01-06 17:47:05
【问题描述】:

尝试让 sed 或 awk 执行以下操作:

  1. 浏览文件
  2. 捕获字符串 + 正则表达式 (remote_addrs.*)
  3. 将整行替换为不同的内容,因此“包含“remote_addrs”及其后的任何内容的行”替换它。

示例文件:

dog
cat
remote_addrs = 1.1.1.1
moose
remote_addrs = 2.2.2.2
woodchuck

想要改成这样: 示例文件:

dog
cat
remote_addrs = 1.1.1.1
moose
remote_addrs = 3.3.3.3
woodchuck

尝试使用以下方法:

sed -z 's/remote_addrs.*/remote_addrs\ =\ 3.3.3.3/2' file
sed ':a;N;$!ba;s/remote_addrs.*/remote_addrs\ =\ 3.3.3.3/2' file

但 sed 拒绝在那次发生后替换所有内容。这似乎只适用于单个字符串。

必须不提供具体行号的情况下完成,“remote_addrs”的行位置必须是可变的。

【问题讨论】:

  • 你为什么要逃离这个空间,尤其是3\3 是对第 3 组的反向引用,并且您的正则表达式中没有单个组。
  • @WiktorStribiżew woops,已编辑,“\”在错误的位置。谢谢。

标签: awk sed replace


【解决方案1】:

使用 awk 你可以试试这个

$ cat file
dog
cat
remote_addrs = 1.1.1.1
moose
remote_addrs = 2.2.2.2
woodchuck

$ awk 'set==1 && /remote_addrs/{ $0="remote_addrs = 3.3.3.3" }
    /remote_addrs/{ set=1 } 1' file
dog
cat
remote_addrs = 1.1.1.1
moose
remote_addrs = 3.3.3.3
woodchuck

【讨论】:

    【解决方案2】:

    虽然 Wiktor 的不错的解决方案已被接受,但 awk 解决方案如何(JFYI):

    awk '/remote_addrs.*/ && c++==1 {sub(/remote_addrs.*/, "remote_addrs = 3.3.3.3")} 1' file
    
    • 正则表达式的第一个匹配项只是增加变量c 而不调用{...} 中的语句。
    • 第二个匹配执行sub() 语句。
    • 最后的1 告诉awk 打印当前记录。

    【讨论】:

      【解决方案3】:

      您使用的是 GNU sed,所以我也发布了 GNU sed 解决方案:

      sed -z 's/remote_addrs.*/remote_addrs = 3.3.3.3/2m' file
      

      注意:

      • \3(在您现在编辑的问题的初始版本中使用)是对第 3 组的反向引用,并且您的正则表达式中没有单个组。所以,应该删除逃逸
      • 您无需转义空格
      • \z 使换行符成为模式空间的一部分,因此. 匹配它们。您需要打开“多行”模式,并添加m 标志,使. 模式无法匹配换行符。

      online demo

      #!/bin/bash
      s='dog
      cat
      remote_addrs = 1.1.1.1
      moose
      remote_addrs = 2.2.2.2
      woodchuck'
       
      sed -z 's/remote_addrs.*/remote_addrs = 3.3.3.3/2m' <<< "$s"
      

      输出:

      dog
      cat
      remote_addrs = 1.1.1.1
      moose
      remote_addrs = 3.3.3.3
      woodchuck
      

      【讨论】:

      • "你需要打开"多行"模式,并添加 m" 就是这样!非常感谢:)
      猜你喜欢
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      • 2019-10-06
      • 2018-07-28
      • 1970-01-01
      • 2011-06-06
      • 2015-09-06
      • 2014-10-28
      相关资源
      最近更新 更多