Original String: allow from 1.1.1.1 9.9.9.9 2.2.2.2
I wanted to replace 9.9.9.9
with 5.5.5.5
e.g. allow from 1.1.1.1 5.5.5.5 2.2.2.2
The Goal is to Replace any string between allow from 1.1.1.1
and 2.2.2.2
Original String: allow from 1.1.1.1 9.9.9.9 2.2.2.2
I wanted to replace 9.9.9.9
with 5.5.5.5
e.g. allow from 1.1.1.1 5.5.5.5 2.2.2.2
The Goal is to Replace any string between allow from 1.1.1.1
and 2.2.2.2
Something like this?
new="5.5.5.5" perl -pe 's/(allow from 1.1.1.1 ).*?( 2.2.2.2)/$1$ENV{new}$2/' $YOUR_FILE
Given a file containing
allow from 1.1.1.1 9.9.9.9 2.2.2.2
allow from 1.1.1.1 x 2.2.2.2
allow from 1.1.1.1 3.3.3 2.2.2.2
It will output this:
allow from 1.1.1.1 5.5.5.5 2.2.2.2
allow from 1.1.1.1 5.5.5.5 2.2.2.2
allow from 1.1.1.1 5.5.5.5 2.2.2.2
It replaced anything between "allow from 1.1.1.1 " and " 2.2.2.2" with the content of the variable $new
defined in front of the perl command.
If you want to make sure you only replace groups of 4 digits separated by dots, you can replace .*?
in the regex with something like \d\.\d\.\d\.\d
. If these are IPv4 addresses you could also use \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
or the less sctrict [\d\.]{7,15}
(7 to 15 characters, all dots or digits).
If you want to do it "in-place" instead of printing the result to STDOUT, you can add -i.bak
as the first option. That will first backup "$YOUR_FILE" to "$YOUR_FILE.bak"
I will assume that the rest of the line is always allow from 1.1.1.1
before the part you want to modify and 2.2.2.2
after the part you want to modify. Try:
string1="allow from 1.1.1.1 9.9.9.9 2.2.2.2"
new=5.5.5.5
string2=$(echo "$string1" | sed "/^\(allow from 1\.1\.1\.1\) .* \(2\.2\.2\.2\)$/s//\1 $new \2/")
If you are not sure of having always 1.1.1.1
or 2.2.2.2
, you will have to modify the regex accordingly, which is quite trivial, as in:
string2=$(echo "$string1" | sed "/^\(allow from [^ ]*\) .* \([^ ]*\)$/s//\1 $new \2/")
I'd use awk, and pass the IP addresses in as parameters:
awk -v start="1.1.1.1" -v end="2.2.2.2" -v repl="5.5.5.5" '
/allow from/ && $3 == start && $5 == end {$4 = repl}
{print}
' file
If you need to save that file in-place, there are several options:
awk ... file > tmpfile && mv tmpfile file
awk ... file | sponge file # requires the `moreutils` package
awk -i inplace -v ... file # requires GNU awk