Padrão de regex para substituir vários valores via sed

0

Eu tenho um script no qual preciso analisar o endereço IP do localhost e substituir o segundo octeto por um valor diferente, mas o valor que está sendo substituído depende do valor atual ...

Por exemplo, se o IP for 10.10.100.6 , então eu preciso que o resultado seja 10.20.100.6 , e se o IP for 10.20.100.6 , então eu preciso que o resultado seja 10.10.100.6

Eu tentei o seguinte:

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\./'

E o problema que estou tendo com isso, é que as substituições sed acontecem na ordem em que elas estão definidas no comando. Então o resultado é sempre 10.10 ....

Existe uma maneira de ter sed substituir valores somente se o valor atual corresponder a um padrão?

Obrigado!

PS Isso precisa ser um pequeno e simples liner, já que esta linha de código será executada via substituição em alguns lugares, e quem fizer isso terá pouca experiência / conhecimento, então basta copiar e colar de um documento.

Atualizar

Acabei descobrindo como fazer isso 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}'

Mas há algumas boas e simples respostas mostrando como fazer isso em sed abaixo.

    
por Justin 02.06.2016 / 20:23

3 respostas

4

Basta adicionar t; .

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

Ela se ramifica até o fim no sucesso. Mas você deveria mesclar todos esses grep, awk, sed em um único awk.

    
por 02.06.2016 / 20:41
1

Para trocar duas strings, use uma terceira string temporária que não será alterada para o outro lado.

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

Não é necessário canalizar grep ou sed para awk ou awk para awk aqui. awk pode fazer tudo, em uma passagem:

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' 

Nas linhas que começam com ipv4.address , se o segundo campo começar com 10.10 , substitua por 10.20 ou, se começar com 10.20 , substitua-o por 10.10 . Imprima todas as linhas, independentemente de terem sido modificadas ou não. (O 1 é um atalho do awk - 1 sempre é avaliado como verdadeiro, e a ação padrão é imprimir ... essa linha é efetivamente if true then print the current line ).

    
por 03.06.2016 / 07:26