Reputation: 11876
I have a file that I'm trying to modify using perl from the terminal in Ubuntu Linux (Natty).
The name of the file is vm.args and the first two lines are as follows:
## Name of the riak node
-name [email protected]
I am trying to use perl to update the ip address. Below is my code:
riak_ip=`ifconfig eth1 | grep "inet addr" | cut -d ":" -f2 | cut -d " " -f1`
perl -0777 -i -pe "s/(\-name[\t ]*riak\@)[^\n]+/\1$riak_ip/g" vm.args
Let's assume the ip address I get is 10.181.106.32. The perl command gives me a result I can't understand. The resulting first two lines in the my file after I run the above in the terminal become:
## Name of the riak node
H.181.106.32
Which is the letter H and part of the ip address.
I can't seem to figure out what I'm doing wrong and will appreciate some assistance.
Thanks in advance.
Upvotes: 1
Views: 194
Reputation: 67900
Sounds like a good use for the \K
sequence (v5.10). And [^\n]
is actually .
, unless the /s
modifier is used. No need for /g
option unless you intend to replace the string several times.
perl -0777 -i -pe "s/\-name[\t ]*riak\@\K.+/$riak_ip/" vm.args
Upvotes: 0
Reputation: 126722
This really should all be done in Perl, which is much better at extracting data from text than shell script. Something like this should work, but I cannot test it at present.
perl -0777 -i -pe '($ip)=`ifconfig eth1`=~/inet addr:([\d.]+)/;s/-name\s+riak@\K[\d.]+/$ip/g;' vm.args
I would be grateful if someone could confirm whether this works OK. Beware that the \K
construct in Perl regexes is a recent addition and may not be in any given installation of Perl.
Upvotes: 1
Reputation: 7058
Problem is that \1
gets concatenated with the first IP octet. To make it work despite concatenation, the ${1}
syntax needs to be used and properly quoted. This works:
perl -0777 -i -pe "s/(\-name[\t ]*riak\@)[^\n]+/\${1}$riak_ip/g" vm.args
You might consider to use single quotes for the regex parts, to remove one layer of quoting:
perl -0777 -i -pe 's/(-name[\t ]*riak@)[^\n]+/${1}'"$riak_ip"'/g' vm.args
(Edited/corrected according to comments, my previous suggestion was wrong.)
Upvotes: 0
Reputation: 59553
This seems to work reliably:
perl -0777 -i -pe "s/(-name\\s*riak@).*/\${1}$riak_ip/g" vm.args
The "\\1$riak_ip
" seems to cause some problems since perl was seeing it as "\1172.20.2.136
" if $riak_ip
was 172.20.2.136. My guess is that the back reference to "1172" was causing some weirdness. Anyway, switching to the ${1}
form removes the possibility for misinterpretation (pun intended).
Upvotes: 2
Reputation: 36262
This would be the correct regexp:
perl -0777 -i -pe "s/(-name\s*riak@)\S+/$1$riak_ip/g" vm.args
Result:
## Name of the riak node
10.181.106.32
Use \s
for space characters, and \S
(no space character) to match the whole IP address. In the replacement string, $1
is used instead \1
. -
and @
are not special, so there is no need to escape them, although there is nothing bad with them.
Upvotes: -1