如何使用 sed 替换文本文件中的非典型模式

如何使用 sed 替换文本文件中的非典型模式

我有一个 MRTG 配置文件,其中包含以单词“Target”开头的行。现在在这些行中有一个以字符“#”开头并以字符“:”结尾的模式。

示例线可能看起来像这些(注意两种类型,但开始/结束标记仍然相同):

   Target[192.168.0.1_Gi1_1]: #Gi1/1:[email protected]:::::2

   Target[192.168.0.1_Gi1_31]: #Gi1/31:[email protected]:::::2

我需要让 sed 找到这些行并"#Gix/n:"用 替换模式"ifInErrors#Gix/n&ifInErrors#Gix/n:",其中 x= 1-9,n= 1-48

因此,上面显示的两条示例线将修改为:

Target[192.168.0.1_Gi1_1]: ifInErrors#Gi1/1&ifInErrors#Gi1/1:[email protected]:::::2

Target[192.168.0.1_Gi1_31]: ifInErrors#Gi1/31&ifInErrors#Gi1/31:[email protected]:::::2

答案1

您需要的是一个捕获组 - 您可以在括号中捕获所需的内容,并可以在替换中引用它。像这样:

 grep ^[[:space:]]*Target file | sed 's/\(#Gi[1-9]\/[1-9][0-9]*\):/ifInErrors\1\&ifInErrors\1:/'

答案2

sed '/Target/s/\(#Gi[0-9]*_[0-9]*:\)/ifInErrors\1\&ifInErrors\1/' input.txt

sed '/Target/相当于grep Target | sed,只是少了一个进程和一个管道。

s/表示“替换”,最常见的 sed 命令;s/foo/bar/将替换字符串的实例酒吧, 例如。

/\(#Gi[0-9]*\/[0-9]*:\)... 括号(需要用 转义\)告诉 sed 将它们之间的所有内容标记为\1(或第二个标记模式的 \2,第三个标记模式的 \3 等)。[0-9]*表示“任意数量的数字”,并且\/是转义的/(需要转义,因为我将其用作/sed 的分隔符;如果您使用另一个分隔符,例如|,则无需转义 /)。因此,#Gi[0-9]*\/[0-9]*:模式的意思是“以 # 开头,后跟 Gi,然后是任意数量的数字,然后是 /,然后是任意数量的数字,以 : 结尾”。

因此\1匹配由模式检测到的任何字符串#Gi[0-9]*\/[0-9]*:在问题中给出的第一个字符串中,

Target[192.168.0.1_Gi1_1]: #Gi1/1:[email protected]:::::2
##  The pattern #Gi[0-9]*\/[0-9]*: will match the substring
#Gi1/1:

...因此/ifInErrors\1\&ifInErrors\1/告诉 sed‘替换#Gi1/1:ifInErrors#Gi1/1:&ifInErrors#Gi1/1:’。

一些额外的东西:如果你想只是打印以“目标”开头的行,进行 sed 替换,您可以使用以下行:

sed -n '/Target/s/\(#Gi[0-9]*\/[0-9]*:\)/ifInErrors\1\&ifInErrors\1/p'

-n告诉 sed“不要打印输出”,p最后的告诉它打印 sed 正在处理的行。

如果您想要覆盖原始文件,可以使用以下命令:

sed -i '/Target/s/\(#Gi[0-9]*\/[0-9]*:\)/ifInErrors\1\&ifInErrors\1/'

相关内容