14

I'm learning about sed but it is very difficult to me understand it.

I have adsl with dynamic ip so and i want to put current ip on hosts file.

This following script just tells me the current wan ip address and no more:

IP=$(dig +short myip.opendns.com @resolver1.opendns.com)
echo $IP

The result:

192.42.7.73

So, i have a line on hosts file with the old ip address:

190.42.44.22   peep.strudel.com

and i want to update host file like this:

192.42.7.73    peep.strudel.com

How can i do it? I think i can use the hostname as pattern...

The reason of doing this is because my server is a client of my router, so it access the internet thru its gateway and not directly. And postfix always is logging me that "connect from unknown [x.x.x.x]" (where x.x.x.x is my wan ip!) and it can't resolve that ip. I think that maybe if i specify this relating with my fqdn host/domain, on hosts file it will works better.

Thanks Sergio.

3 Answers 3

20

You can use a simple shell script:

#! /bin/bash

IP=$(dig +short myip.opendns.com @resolver1.opendns.com)

HOST="peep.strudel.com"

sed -i "/$HOST/ s/.*/$IP\t$HOST/g" /etc/hosts

Explanation:

sed -i "/$HOST/ s/.*/$IP\t$HOST/g" /etc/hosts means in the line which contains $HOST replace everything .* by $IP tab $HOST.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks Tiago, i like your solution, very simple and clear to understand.
One thing i found is dig always returns a zero exit code so could mess up your hosts file. Excellent use of sed should have been accepted answer.
6

using sed

sed -r "s/^ *[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+( +peep.strudel.com)/$IP\1/"

. [0-9]+\. find all lines that matches 1 or more digits with this pattern 4 consecutive times then pattern peep.strudel.com .The parenthesis around the pattern peep.strudel.com save it as \1 then replace the whole patten with your variable and your new ip.

another approach:instead of saving pattern to a variable named IP, you can execute your command line inside sed command line to get the new IP .

   sed -r "s/^ *[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+( +peep.strudel.com)/$(dig +short myip.opendns.com @resolver1.opendns.com)\1/"

using gawk

gawk -v IP=$IP '/ *[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+( +peep.strudel.com).*/{print gensub(/ *[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+( +peep.strudel.com)/,IP"\\1","g")}'

3 Comments

thanks, i used your second example (all in 1 command line), added -i parameter to sed for saving the file, as Avinash Raj and Tiago suggested. It works :) (note: i added more spaces before ( +peep.strudel.com), matching the editing of original post)
great! :D.I catered for the spaces in my command line using this piece of code " +" after peep.strudel.com
I +1 this question so that you can reach 15 rep to vote!
3

You need to include the sed code inside double quotes so that the used variable got expanded.

sed "s/\b\([0-9]\{1,3\}\.\)\{1,3\}[0-9]\{1,3\}\b/$IP/g" file

Add -i parameter to save the changes made. In basic sed \(..\) called capturing group. \{min,max\} called range quantifier.

Example:

$ IP='192.42.7.73'
$ echo '190.42.44.22   peep.strudel.com' | sed "s/\b\([0-9]\{1,3\}\.\)\{1,3\}[0-9]\{1,3\}\b/$IP/g"
192.42.7.73   peep.strudel.com

1 Comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.