0

I have a script in which I need to parse the IP address of the localhost, and replace the 2nd octet with a different value, but the value being substituted depends on what the value currently is...

For example, if the IP is 10.10.100.6, then I need the result to be 10.20.100.6, and if the IP is 10.20.100.6, then I need the result to be 10.10.100.6

I tried the following:

nmcli con show eno16777984 | grep -E '^ipv4.address' | awk -F"/|[[:space:]]+" '{print $2}' | sed -e 's/^10\.10\./10.20./; s/^10\.20\./10\.10\./'

And the problem I'm having with that, is that the sed substitutions happen in order they are set in the command. So the result is always 10.10....

Is there a way to have sed replace values only if the current value matches a pattern?

Thanks!

P.S. This needs to be a short and simple one liner, as this line of code will be executed via substitution in a few places, and whoever does it will have limited experience/knowledge, so will just be copying and pasting from a document.

Update

I ended up finding out how to do this via awk:

nmcli con show eno16777984 | grep -E '^ipv4.address' | awk -F"/|[[:space:]]+" '{print $2}' | awk -F. '{print $1"."($2 == "10" ? "20" : "10")"."$3"."$4}'

But there are some good and simple answers showing how to do it in sed below.

  • As a side note, you may be able to replace the nmcli, grep and awk by a single hostname -i. Or maybe it'll return the IPv6, but if you haven't tried yet it's worth a shot. – Aaron Jun 2 '16 at 18:46
4

Just add t;.

sed -e 's/^10\.10\./10.20./;t;s/^10\.20\./10\.10\./'

It branches to the end on success. But you should really merge all these grep, awk, sed into a single awk.

  • Oh wow, nice. I ended up figuring out how to do it using awk, (updating post), but this works as well! (Since the question was in fact, how to accomplish it using SED... this is a better answer than mine) – Justin Jun 2 '16 at 20:49
1

To exchange two strings, use a temporary 3rd string that won't be changed back the other way.

sed -e 's/^10\.10\./10.foo./g; s/^10\.20\./10.10./g; s/^10\.foo\./10.20./g'
0

There's no need to pipe grep or sed into awk, or awk into awk here. awk can do it all, in one pass:

nmcli con show eno16777984 | 
  awk -F"/|[[:space:]]+" '
    /^ipv4.address/ {
      if ($2 ~ /^10\.10/) {
        sub(/10\.10/,"10.20",$2);
      } else if ($2 ~ /^10\.20/) {
        sub(/10\.20/,"10.10",$2);
      };
    };

    1' 

On lines beginning with ipv4.address, if the second field begins with 10.10, replace that with 10.20 or if it begins with 10.20, replace it with 10.10. Print all lines whether they were modified or not. (The 1 is an awk shortcut - 1 always evaluates to true, and the default action is to print...that line is effectively if true then print the current line).

  • This works pretty well! I changed it a little to only print the IP, src – Justin Jun 7 '16 at 18:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.