Reputation: 953
I used the following Perl syntax in order to replace strings or IP address in a file:
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
example of problem:
I want to change the IP address in file from 1.1.1.1 to 5.5.5.5
But I get the following:
more file (before change)
11.1.1.10 machine_moon1
more file (after change)
15.5.5.50 machine_moon1
According to "after change example) the IP "11.1.1.10" must to stay as it is , because I want to change only the 1.1.1.1 and not 11.1.1.10
I need help about my perl one line syntax:
How to change my perl syntax only according to the following rule:
RULE: Not change the IP address if:left IP side or right IP side have number/s
Example
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
Upvotes: 0
Views: 1162
Reputation: 4946
Here's what you start with:
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
If you anchor the patterns to only match on word boundaries or non-digits (see perlre), you should only match a complete IP address:
~/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
Upvotes: 2
Reputation: 35788
It might be easier to write a short script to do this.
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;
Upvotes: 0
Reputation: 185053
You should use look-behind and look-ahead syntax, see a good article on perlmonks : http://www.perlmonks.org/?node_id=518444
Upvotes: 1