Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Perl仅替换文件中的完整IP地址?_Perl - Fatal编程技术网

如何使用Perl仅替换文件中的完整IP地址?

如何使用Perl仅替换文件中的完整IP地址?,perl,Perl,为了替换文件中的字符串或IP地址,我使用了以下Perl语法: OLD=aaa.bbb.ccc.ddd (old IP address) NEW=yyy.zzz.www.qqq (new IP address) export OLD export NEW perl -pe 'next if /^ *#/; s/\Q$ENV{OLD }\E/$1$ENV{NEW }$2/' file 问题示例: 我想将文件中的IP地址从1.1.1.1更改为5.5.5.5 但我得到了以下信息

为了替换文件中的字符串或IP地址,我使用了以下Perl语法:

 OLD=aaa.bbb.ccc.ddd   (old IP address)
 NEW=yyy.zzz.www.qqq   (new IP address)

 export OLD
 export NEW

 perl  -pe 'next if /^ *#/; s/\Q$ENV{OLD }\E/$1$ENV{NEW }$2/' file
问题示例:

我想将文件中的IP地址从1.1.1.1更改为5.5.5.5

但我得到了以下信息:

more file (before change)

11.1.1.10 machine_moon1



more file (after change)

15.5.5.50 machine_moon1
根据更改后示例,IP 11.1.1.10必须保持原样,因为我只想更改1.1.1.1,而不是11.1.1.10

我需要有关perl单行语法的帮助:

如何仅根据以下规则更改perl语法:

  RULE: Not change the IP address if:left IP side or right IP side have number/s 
范例

 IP=1.1.1.1    
 IP=10.10.1.11
 IP=yyy.yyy.yyy.yyy

 [number]1.1.1.1[number]    - then not replace

 [number]10.10.1.11[number]    - then not replace

 [number]yyy.yyy.yyy.yyy[number]    - then not replace



Other cases:

  [any character beside number ]yyy.yyy.yyy.yyy[[any character beside number ]] - then replace

您应该使用look-behind和look-ahead语法,请参阅关于perlmonks的一篇好文章:

您应该使用look-behind和look-ahead语法,请参阅关于perlmonks的一篇好文章:

编写一个简短的脚本可能更容易做到这一点

use strict;
use autodie;

my $old_ip = 10.1.1.1; # or $ENV{'OLD'}
my $new_ip = 50.5.5.5; # or $ENV{'NEW'}

open my $infh, '<', $ARGV[0];
open my $outfh, '>', $ARGV[1];
while ( my $line = <$infh> ) {
  chomp $line;
  my @elems = split '\s+', $line;
  next unless $elems[0] eq $old_ip;
  print $outfh $new_ip . join(" ", @elems[1..$#elems]) . "\n";
}
close $outfh;
close $infh;

编写一个简短的脚本来实现这一点可能更容易

use strict;
use autodie;

my $old_ip = 10.1.1.1; # or $ENV{'OLD'}
my $new_ip = 50.5.5.5; # or $ENV{'NEW'}

open my $infh, '<', $ARGV[0];
open my $outfh, '>', $ARGV[1];
while ( my $line = <$infh> ) {
  chomp $line;
  my @elems = split '\s+', $line;
  next unless $elems[0] eq $old_ip;
  print $outfh $new_ip . join(" ", @elems[1..$#elems]) . "\n";
}
close $outfh;
close $infh;

以下是您开始的内容:

OLD=1.1.1.1
NEW=5.5.5.5

export OLD
export NEW

~/sandbox/$ cat file
1.1.1.10  machine1
11.1.1.10 machine2
11.1.1.1  machine3
1.1.1.1   machine4
A1.1.1.1  machine5
A1.1.1.1  machine6
1.1.1.1Z  machine7
如果将模式定位为仅在单词边界或非数字上匹配,请参见,则应仅匹配完整的IP地址:

~/sandbox/$ perl -pe 'next if /^ *#/; s/(\b|\D)$ENV{OLD}(\b|\D)/$1$ENV{NEW}$2/' file
1.1.1.10  machine1
11.1.1.10 machine2
11.1.1.1  machine3
5.5.5.5   machine4
A5.5.5.5  machine5
A5.5.5.5Z machine6
5.5.5.5Z  machine7

以下是您开始的内容:

OLD=1.1.1.1
NEW=5.5.5.5

export OLD
export NEW

~/sandbox/$ cat file
1.1.1.10  machine1
11.1.1.10 machine2
11.1.1.1  machine3
1.1.1.1   machine4
A1.1.1.1  machine5
A1.1.1.1  machine6
1.1.1.1Z  machine7
如果将模式定位为仅在单词边界或非数字上匹配,请参见,则应仅匹配完整的IP地址:

~/sandbox/$ perl -pe 'next if /^ *#/; s/(\b|\D)$ENV{OLD}(\b|\D)/$1$ENV{NEW}$2/' file
1.1.1.10  machine1
11.1.1.10 machine2
11.1.1.1  machine3
5.5.5.5   machine4
A5.5.5.5  machine5
A5.5.5.5Z machine6
5.5.5.5Z  machine7


hi CanSpice-我的目标是修复我的perl单行语法以支持我的案例,但我不能使用您的示例,因为perl语法是我bash的一部分script@jon=>您始终可以将代码保存到一个文件中,并使用perl从脚本中调用该文件,有些问题最好以长格式解决好我会在其他情况下这样做,但请参阅@Sir solution-他的解决方案是我所需要的通常当人们需要一行时,没有任何额外的文件分发给他们的shell脚本makefile,hi CanSpice-我的目标是修复我的perl单行语法,以支持我的案例,但我不能使用您的示例,因为perl语法是我bash的一部分script@jon=>您始终可以将代码保存到一个文件中,并使用perl从脚本中调用该文件,有些问题最好以长格式解决好我会在其他情况下这样做,但请参阅@Sir solution-他的解决方案是我所需要的通常当人们需要一行时,没有任何额外的文件分发给他们的shell脚本makefile,如果右侧或左侧没有数字,则不起作用,例如:echo A1.1.1.1 | perl-pe'next if/^*/;s/\b$ENV{OLD}\b/$ENV{NEW}/'好吧,OP没有指定,但是这个版本是关于你要找的吗?请注意,我刚刚将\D非数字更改为\b | \D单词边界或非数字,并使用parens进行了捕获。是的,现在可以了,如果它在perl挖掘中\D启用charecterThanks=多年的困难时间;。是一个元字符。首先,我会做一些类似于$re=qr/\b\Q$ENV{OLD}\E\b/;,然后,如果右侧或左侧有非数字,则s/$re/$ENV{NEW}/it不起作用,例如:echo A1.1.1.1 | perl-pe'next if/^*/;s/\b$ENV{OLD}\b/$ENV{NEW}/'好吧,OP没有指定,但是这个版本是关于你要找的吗?请注意,我刚刚将\D非数字更改为\b | \D单词边界或非数字,并使用parens进行了捕获。是的,现在可以了,如果它在perl挖掘中\D启用charecterThanks=多年的困难时间;。是一个元字符。首先,我会做一些类似于$re=qr/\b\Q$ENV{OLD}\E\b/;,然后s/$re/$ENV{NEW}/