我在文件中有以下线条样式:
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/;'