使用“sed”匹配整个单词(IP 地址)

使用“sed”匹配整个单词(IP 地址)

我在文件中有以下线条样式:

1.2.3.4
1.2.3.4a
1.2.3.45
iaa1.2.3.4ad
11.2.3.4a
a1.2.3.4
1.2.3.4>
<1.2.3.4>
<"1.2.3.4">
1.2.3.4 hostname

我想替换所有的ip'1.2.3.4' 使用另一个 ip,例如 '9.8.7.6',包括在 <> 和 "" 中,并且在 ip 之前或之后带有一个字母。

不是这 '11.2.3.4' 或者 '1.2.3.45'

所以编号 1.2.4.6.7.8.9.10 均匹配。

注意:“1.2.3.4”只是一个示例,它可以是任何有效的 ip。

我想用另一个ipsed来替换。1.2.3.4

我不知道命令怎么写sed

sed "s/oldip/newip/g"

我对正则表达式了解一点,但这对我来说似乎太难了。

谢谢。

答案1

您还没有说出您想要对不包含有效 IP 的行执行什么操作,因此我假设您只是想忽略它们。然后,您需要做的就是确保整行匹配三组一到三个数字 ( [0-9]{1,3}),然后匹配最后一组一到三个数字。以下是三种方法:

  • GNU sed

    sed -r 's/^([0-9]{1,3}\.){3}[0-9]{1,3}$/5.6.7.8/' file
    
  • 非 GNU sed

    sed  's/^\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}$/5.6.7.8/' file
    
  • Perl

    perl -pe 's/^(\d{1,3}\.){3}\d{1,3}$/5.6.7.8/' file
    

答案2

如果您使用现代 sed,则可以执行以下操作:

sed -e 's/\(^\|[^0-9]\)1\.2\.3\.4\($\|[^0-9]\)/\1NEWIP\2/'

即,如果位于行首或前面为非数字,则替换1.2.3.4为, 如果另外位于行尾或后面为非数字。NEWIP

对于不支持扩展正则表达式的旧 sed 版本,情况会更加复杂。例如,您可以使用标记字符来做到这一点。我们需要两个保证不会出现在输入中的字符。在下面的解决方案中,我在这里使用,:,但任何其他字符都可以,甚至是控制字符。

sed -e 's/\(1\.2\.3\.4\)/,\1:/;s/\([0-9]\),/\1/;s/:\([0-9]\)/\1/;s/,.*:/NEWIP/;s/[,:]//'

我们首先在要替换的模式,之前和之后插入;:然后我们删除,if 前面有一个数字,:如果后面有一个数字;然后我们用替换字符串替换字符串 from ,to (如果仍然存在);:最后我们删除任何剩余的,:

使用 Perl,还可以使用否定的前瞻断言(?!\d)和否定的后视断言(?<!\d)来确保模式仅在前面或后面没有数字的情况下匹配:

perl -pe 's/(?<!\d)1\.2\.3\.4(?!\d)/NEWIP/;'

相关内容