如何在Perl中仅替换IP地址的三个第一个八位字节

时间:2012-12-26 12:15:23

标签: linux bash perl shell regex

我的目标是用新IP地址替换IP地址中的前三位数字 例如

 NEW three first three digits – 17.100.10
 OLD three first three digits - 12.200.10 
 Existing IP address in file  - 12.200.10.2 

然后我将获得新的IP 17.100.10.2

所以我编写了以下Perl命令以执行替换操作

但问题是,如果新IP匹配最后三位数字,那么它也会替换它们

所以

我的Perl命令需要更改什么才能只替换IP地址中的三个第一位数?

描述问题的Real Example1:

export OLD_IP=192.9.1
export NEW_IP=172.192.9

echo 1.192.9.1 | perl -i -pe 'next if /^ *#/; s/(\b|\D)$ENV{OLD_IP}(\b|\D)/$1$ENV      {NEW_IP}$2/g'  
 1.172.192.9

3 个答案:

答案 0 :(得分:4)

#!/bin/perl

my @ip = split('\.', $old_ip);
$ip[0] = 172;
$ip[1] = 16;
$ip[2] = 0;
$new_ip = join(".", @ip);

#!/bin/perl

my @ip = split('\.', $old_ip);
$new_ip = '172.16.0.' . $ip[3];

s/(\d{1,3}\.){3}(?=(\d+$))/$ENV{new_ip}/

单线,WTF,版本;应该放入你的shell脚本......

# export new_ip=172.168.0.
# echo 192.168.5.6 | perl -i pe 's/(\d{1,3}\.){3}(?=(\d+$))/$ENV{new_ip}/'
172.16.0.6

答案 1 :(得分:3)

这只是您的代码存在的三个问题之一。另外两个是:

  • 您的代码将192.9.100.1(OLD_IP = 192.9.1)更改为172.192.900.1(NEW_IP = 172.192.9)。

  • 您的代码将192.101.1.2(OLD_IP = 192.1.1)更改为172.192.9.1.2(NEW_IP = 172.192.9)。

解决方案:

perl -pe's/(?<![\d.])\Q$ENV{OLD_IP}\E(?=\.\d)/$ENV{NEW_IP}/g'

注意:

    如果IP地址始终位于一行的开头,则
  • ^甚至会优于(?<![\d.])。 (/g会变得毫无用处。)
  • 如果IP地址始终以空格,制表符开头或始终位于行首,则
  • (?<!\S)甚至会优于(?<![\d.])

答案 2 :(得分:0)

如果每个IP地址都出现在一行,这很容易:

s/^\Q$ENV{OLD_IP}\E/$ENV{NEW_IP}/mg

如果没有,你可以使用负面的lookbehind断言:

s/(?<![\d.])\Q$ENV{OLD_IP}\E/$ENV{NEW_IP}/g

这将匹配并替换OLD_IP中给出的字符串,除非它跟随数字或句点。

修改:要修复ikegami指出的问题,您还应确保匹配的字符串后面没有数字:

s/(?<![\d.])\Q$ENV{OLD_IP}\E(?!\d)/$ENV{NEW_IP}/g

与ikegami的解决方案不同,这适用于任意数量的八位字节,而不仅仅是三个或更少。