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

Posted

技术标签:

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

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

    浏览文件 捕获字符串 + 正则表达式 (remote_addrs.*) 将整行替换为不同的内容,因此“包含“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,已编辑,“\”在错误的位置。谢谢。 【参考方案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" 就是这样!非常感谢:)

以上是关于sed / awk 匹配文件中第二次出现的正则表达式,并替换整行的主要内容,如果未能解决你的问题,请参考以下文章

使用awk / grep / sed / bash / vim进行正则表达式匹配和打印

awk one-liner 仅替换第一个匹配的正则表达式出现的文本

如何使用 sed、awk 或 gawk 仅打印匹配的内容?

linux 下的 正则表达式(awk,sed,awk)学习

grep sed awk

正则表达式解析 & awk/sed/grep实用实例总结文档