Linux - NewbieThis 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
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
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.
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.
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.
$ 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)); };
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.