sed / awk 匹配文件中第二次出现的正则表达式,并替换整行



尝试让 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"的行位置必须是可变的。

虽然Wiktor的好解决方案已被接受,但awk解决方案(JFYI)怎么样:

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

您正在使用GNUsed,所以我也发布了GNUsed解决方案:

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

注意:

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

查看在线演示:

#!/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

使用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

最新更新