0

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

Edcel Cabrera Vista
  • 1,087
  • 1
  • 9
  • 29
  • Does this answer your question? [Replace a string in shell script using a variable](https://stackoverflow.com/questions/3306007/replace-a-string-in-shell-script-using-a-variable) – dt170 May 06 '20 at 12:07
  • Nope. I need to replace an "unknown string" between two patters, thats possible if the string to be replace is known but in my case it's not known; so I think it will be possible to get those unknown string to be replace using known patterns – Edcel Cabrera Vista May 06 '20 at 12:10

3 Answers3

0

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"

mivk
  • 13,452
  • 5
  • 76
  • 69
0

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/")
Pierre François
  • 5,850
  • 1
  • 17
  • 38
  • 1
    I edited the sed regex to sed `"/\(allow from 1\.1\.1\.1\) .* \(2\.2\.2\.2\)/s//\1 $new \2/"` for cases which the original string has content in the start and at the end string. But it works! Thanks! Accepting the answer.. – Edcel Cabrera Vista May 07 '20 at 06:10
0

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
glenn jackman
  • 238,783
  • 38
  • 220
  • 352