LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 01-05-2012, 05:13 PM   #1
cchuey01
LQ Newbie
 
Registered: Jan 2012
Posts: 4

Rep: Reputation: Disabled
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
 
Old 01-05-2012, 05:37 PM   #2
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 374Reputation: 374Reputation: 374Reputation: 374
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.
 
Old 01-05-2012, 05:40 PM   #3
Wellesly
LQ Newbie
 
Registered: Jan 2011
Distribution: Arch Linux
Posts: 16

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

E: Ninja’d
 
1 members found this post helpful.
Old 01-05-2012, 05:56 PM   #4
cchuey01
LQ Newbie
 
Registered: Jan 2012
Posts: 4

Original Poster
Rep: Reputation: Disabled
The following worked:

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

Thank you VERY MUCH for helping me on this.

Regards,

CHuey
 
Old 01-05-2012, 06:16 PM   #5
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
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.
 
Old 01-05-2012, 06:31 PM   #6
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 374Reputation: 374Reputation: 374Reputation: 374
Quote:
Originally Posted by cchuey01 View Post
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.

Last edited by Dark_Helmet; 01-05-2012 at 06:34 PM.
 
Old 01-05-2012, 07:07 PM   #7
cchuey01
LQ Newbie
 
Registered: Jan 2012
Posts: 4

Original Poster
Rep: Reputation: Disabled
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?

Last edited by cchuey01; 01-05-2012 at 07:09 PM. Reason: Asked if a single sed command can be used to address all possibilities of an IP address within a config file.
 
Old 01-05-2012, 07:44 PM   #8
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 374Reputation: 374Reputation: 374Reputation: 374
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)); };
 
1 members found this post helpful.
Old 01-05-2012, 07:52 PM   #9
cchuey01
LQ Newbie
 
Registered: Jan 2012
Posts: 4

Original Poster
Rep: Reputation: Disabled
Thank you Dark_Helmet... it did work!!! I was not familiar with the "@" usage, so I learned something very valuable.

Regards,

CHuey
 
Old 01-05-2012, 08:15 PM   #10
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 374Reputation: 374Reputation: 374Reputation: 374
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.

Last edited by Dark_Helmet; 01-05-2012 at 08:22 PM.
 
1 members found this post helpful.
Old 01-05-2012, 11:24 PM   #11
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,362

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


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Using sed - search and replace seebee Programming 5 06-07-2011 09:47 PM
[SOLVED] Using sed to search and replace backwards jimieee Programming 15 10-25-2010 10:13 AM
sed search replace tomerbd1 Linux - General 9 04-10-2008 04:31 AM
Bit complicated sed search & replace sharathkv25 Programming 6 04-07-2007 01:53 PM
sed search & replace sharathkv25 Programming 2 03-07-2007 10:16 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 10:14 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration