Match a whole word (IP address) using `sed`
Solution 1
If you use a modern sed, the following works:
sed -e 's/\(^\|[^0-9]\)1\.2\.3\.4\($\|[^0-9]\)/\1NEWIP\2/'
I.e., replace 1.2.3.4
by NEWIP
, if at the beginning of the line or preceded by a non-digit, and if additionally at the end of the line or followed by a non-digit.
With an old sed version that doesn't support extended regexps, it's more complicated. You can do it, e.g., using marking characters. We need two characters that are guaranteed not to occur in the input. In the solution below, I use ,
and :
here, but any other characters will do, even control characters.
sed -e 's/\(1\.2\.3\.4\)/,\1:/;s/\([0-9]\),/\1/;s/:\([0-9]\)/\1/;s/,.*:/NEWIP/;s/[,:]//'
We first insert ,
before and :
after the pattern that we want to replace; then we delete ,
if preceded by a digit and :
if followed by a digit; then we replace the string from ,
to :
(if still present) by the replacement string; finally we delete any remaining ,
or :
.
With perl, one could also use a negative look-ahead assertion (?!\d)
and a negative look-behind assertion (?<!\d)
to ensure that the pattern only matches if not preceded or followed by a digit:
perl -pe 's/(?<!\d)1\.2\.3\.4(?!\d)/NEWIP/;'
Solution 2
You have not said what you want done with the lines that don't contain a valid IP so I assume you just want to ignore them. Then, all you need to do is make sure the entire line matches three groups of one to three numbers ([0-9]{1,3}
), then a final group of one to three numbers. Here are three ways of doing that:
GNU sed
sed -r 's/^([0-9]{1,3}\.){3}[0-9]{1,3}$/5.6.7.8/' file
Non-GNU sed
sed 's/^\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}$/5.6.7.8/' file
Perl
perl -pe 's/^(\d{1,3}\.){3}\d{1,3}$/5.6.7.8/' file
Related videos on Youtube
NabilJaran
Updated on September 18, 2022Comments
-
NabilJaran over 1 year
I have the following line style in a file:
1.2.3.4 1.2.3.4a 1.2.3.45 iaa1.2.3.4ad 11.2.3.4a a1.2.3.4 1.2.3.4> <1.2.3.4> <"1.2.3.4"> 1.2.3.4 hostname
I want to replace all the ip '1.2.3.4' with another ip, such as '9.8.7.6', including in <> and in "" and with a letter preceded or followed by the ip.
But NOT the '11.2.3.4' or the '1.2.3.45'
So No. 1.2.4.6.7.8.9.10 are both matched.
Note: '1.2.3.4' is just an example here, It can be any valid ips.
I want to use
sed
to replace1.2.3.4
with another ip.I don't know how to write the
sed
command.sed "s/oldip/newip/g"
I know a little about regular expression but this is seems too difficult for me.
Thank you.
-
Costas over 9 years
sed -E 's/([0-9]{1,3}\.){3}[0-9]/other_ip/'
-
terdon over 9 yearsWhen asking questions like this, please always include your desired output. If you just show your input it is very hard to understand.
-
-
terdon over 9 yearsNeither of these works, they both replace almost everything but miss real IPs. Try it on the OP's file, you'll see things like
iaaNEWIPad
andaNEWIP
. The OP only wants to replace valid IPs. Also, I doubt the actual IPs are1.2.3.4
, that's just an example so you need a solution that works with any numbers. -
Uwe over 9 years@terdon The original question is unclear. Essentially, the OP asks two questions that should have different solutions. After the example, he says that he wants to match No. 1, 2, 4, 6, 7, 8, 9 (where 1.2.3.4 is potentially preceded or followed by a letter), but not 3 and 5 (where 1.2.3.4 is preceded or followed by a number, resulting in a different IP). So it seems that
iaaNEWIPad
(from No. 4) is indeed an expected result. If not, the OP should make his question more precise. -
terdon over 9 yearsFair enough, I read through the Q quickly and understood one thing but you're quite right, it can also be interpreted in the way you did. The OP should clarify. Anyway, sorry for the unwarranted (as it turns out) downvote, I made an edit so I could retract it.
-
NabilJaran over 9 years@terdon I'm sorry, I didn't describe the question clearly, I want to replace the whole '1.2.3.4' with another ip. I will edit the question. Thank you.
-
NabilJaran over 9 years@Uwe I have updated the question, I hope you can understand me. Thank you.
-
Ludwig Schulze over 9 yearsFor what OP describes, it is just 4 single numbers separated by a single dot, instead of valid IP's, since he doesn't want the '11.2.3.4' nor '1.2.3.45' replaced.
-
NabilJaran over 9 years@terdon 1.2.3.4 is only an example, It may be any valid ips.
-
NabilJaran over 9 years@terdon I'm sorry, but it doesn't work, the ip may be not at the front of the line. And '1.2.3.45' should not be replaced.