LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Using sed to Search & Replace IP Address (https://www.linuxquestions.org/questions/linux-newbie-8/using-sed-to-search-and-replace-ip-address-922286/)

cchuey01 01-05-2012 05:13 PM

Using sed to Search & Replace IP Address
 
Hello.

I would like to use sed to search and replace all occurrences of a specific IP address within a configuration file. To illustrate what I would like to do:

currIP=10.2.123.1
newIP=10.2.123.3

Config File:
some text 10.2.123.10 some text 10.2.123.1
more text

I am struggling with a sed command (using regex) that replaces "10.2.123.1" with "10.2.123.3" and does NOT change "10.2.123.10" to "10.2.123.30".

Any advice/help on this would be GREATLY appreciated.

Thanks,
CHuey

Dark_Helmet 01-05-2012 05:37 PM

The following command worked on the example you provided:
Code:

echo "some text 10.2.123.10 some text 10.2.123.1" | sed 's@\b10\.2\.123\.1\b@10.2.123.3@g'
some text 10.2.123.10 some text 10.2.123.3

The '\b' represents a "word boundary" if I'm not mistaken.

Wellesly 01-05-2012 05:40 PM

\b matches between a word character and a non-word character. sed "s/\(10\.2\.123\.\)1\b/\13/g" works.

E: Ninja’d

cchuey01 01-05-2012 05:56 PM

The following worked:

sed -i -e 's/'$currip'\b/'$newip'/g'

Thank you VERY MUCH for helping me on this.

Regards,

CHuey

David the H. 01-05-2012 06:16 PM

Try just using a single set of double quotes around the expression.

Code:

sed -i -e "s/$currip\b/$newip/g"
The way you were doing it, in addition to being complicated and harder to read, leaves the variable contents open to word-splitting by the shell. Not that it's a problem with a single ip address though.


And please use [code][/code] tags around your code and data, to preserve formatting and to improve readability.

Dark_Helmet 01-05-2012 06:31 PM

Quote:

Originally Posted by cchuey01 (Post 4567390)
sed -i -e 's/'$currip'\b/'$newip'/g'

Agree with David the H about using single quotes, but I'd like to point out some potential danger. You use '\b' only once. You run the same risk of incorrect substitution at the front of your substitution as you were concerned with happening at the end.

For example, suppose:
currip=10.2.123.1
newip=10.2.123.3

And your file contains:
some text 210.2.123.1 some text 10.2.123.1

Your existing command:
Code:

echo "some text 210.2.123.1 some text 10.2.123.1" | sed 's/'$currip'\b/'$newip'/g'
some text 210.2.123.3 some text 10.2.123.3

To be 100% safe, I would suggest the '\b' at the beginning of the pattern match as well as then end like I used in my original command.

EDIT:
To be 200% safe, you also need to make sure that the dots in your currip variable are escaped to prevent sed from treating them as wildcards.

cchuey01 01-05-2012 07:07 PM

Thank you for the advise... it is definitely better to be 100+% safe.

I have another question:

What regex should I use if the IP address is not on a word boundary. For example:

currIP=10.2.123.1
newIP=10.2.123.3

Config File:
line 1: some text 10.2.123.10 more text 10.2.123.1
line 2: source s_ext { tcp(ip(10.2.123.1) port (8514)); };

I need to generate a sed command to replace "10.2.123.1" with "10.2.123.3" in lines 1 & 2 and NOT change "10.2.123.10" to "10.2.123.30" in line 1.

Is it possible to use the same sed command to cover both lines in the Config File above?

Dark_Helmet 01-05-2012 07:44 PM

The same command works for me. For instance:
Code:

$ currip="10\\.2\\.123\\.1"
$ newip="10.2.123.3"
$ cat configfile.txt
some text 10.2.123.10 more text 10.2.123.1
source s_ext { tcp(ip(10.2.123.1) port (8514)); };
$ sed "s@\b${currip}\b@${newip}@g" configfile.txt
some text 10.2.123.10 more text 10.2.123.3
source s_ext { tcp(ip(10.2.123.3) port (8514)); };


cchuey01 01-05-2012 07:52 PM

Thank you Dark_Helmet... it did work!!! I was not familiar with the "@" usage, so I learned something very valuable.

Regards,

CHuey

Dark_Helmet 01-05-2012 08:15 PM

Just to add in case someone finds this thread through Google...

sed's substitution command can use different characters to delimit the search and replace portions of the substitution. The '@' is no different than '/' in sed's eyes--they are functionally equivalent.

The reason I use the @ by default is because I use a lot of escape sequences in my regexs and sometimes use path components. For my purposes, using the forward slash could make for some ugly, unreadable commands. For instance, to adjust a path of /home/fred/ or /home/barney/ to be /home/backup/fred/ or /hom/backup/barney/ respectively:
Code:

echo "/home/fred/" | sed "s/\/home\/\(fred\|barney\)\//\/home\/backup\/\1\//"
/home/backup/fred/

versus
Code:

echo "/home/fred/" | sed "s@/home/\(fred\|barney\)/@/home/backup/\1/@"
/home/backup/fred/

I use the '@' inside my matching far less often than '/' and so, makes sense to use '@' to avoid extra escapes.

chrism01 01-05-2012 11:24 PM

Indeed LTS https://en.wikipedia.org/wiki/Leanin...hpick_syndrome


All times are GMT -5. The time now is 11:01 AM.