【问题标题】:Use sed or awk to replace line after match匹配后使用 sed 或 awk 替换行
【发布时间】:2016-05-27 02:42:46
【问题描述】:

我正在尝试创建一个基本上使用 dig +short 来查找网站的 IP 的小脚本,然后将其通过管道传送到 sed/ awk/grep 替换一行。这是当前文件的样子:

#Server
123.455.1.456
246.523.56.235

所以,基本上,我想在文本文件中搜索“#Server”行,然后用从 dig 获取的 IP 地址替换它下面的两行强>。

我了解 sed 的一些语法,但我真的很难弄清楚如何替换匹配项下的两行。非常感谢任何帮助。

【问题讨论】:

  • 投反对票:向我们展示您为解决问题所做的一些努力。请记住,SO 不是我网站的免费代码。阅读minimal reproducible example。开始的提示是使用带有sed 的 n/N 选项。
  • sed 用于在单个行上进行简单替换,仅此而已。对于其他任何事情,例如这个问题,你应该用awk。发布简洁、可测试的示例输入和预期输出,以便我们开始帮助您解决问题。

标签: linux bash shell awk sed


【解决方案1】:

根据 OP,还不是 100% 明确需要在哪里替换什么,但这里有一个针对一般情况的单行代码,使用 GNU sedbash .将“3”后面的两行替换为标准输入

echo Hoot Gibson | sed -e '/3/{r /dev/stdin' -e ';p;N;N;d;}' <(seq 7)

输出:

1
2
3
Hoot Gibson
6
7

注意:sedr 命令的文档不透明(无论如何在 Linux 中)。有关 r 的更多信息,请参阅:
5.9. 'r' 命令没有将文件插入到文本中”在这个sed FAQ 中。

【讨论】:

    【解决方案2】:

    awk

    newip=12.34.56.78
    
    awk -v newip=$newip '{
      if($1 == "#Server"){
        l = NR;
        print $0
      }
      else if(l>0 && NR == l+1){
        print newip
      }
      else if(l==0 || NR != l+2){
        print $0
      }
    }' file > file.tmp
    
    mv -f file.tmp file
    

    解释:

    1. $newip 传递给awk
    2. 如果当前行的第一个字段是#Server,则设l = 当前行号。
    3. 如果当前行超过#Server,则打印新的ip。
    4. 否则,如果当前行不是#Server 之后的两行,则打印该行。
    5. 用修改后的版本覆盖原始文件。

    【讨论】:

      最近更新 更多