Combine uma palavra inteira (endereço IP) usando 'sed'

0

Eu tenho o seguinte estilo de linha em um arquivo:

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

Eu quero substituir todo o ip ' 1.2.3.4 ' por outro ip, como ' 9.8.7.6 ', incluindo em < > e em "" e com uma letra precedida ou seguida pelo ip.

Mas NÃO o ' 11.2.3.4 ' ou o ' 1.2.3.45 '

Então Não. 1.2.4.6.7.8.9.10 são ambos combinados.

Nota: '1.2.3.4' é apenas um exemplo aqui, pode ser qualquer ips válido.

Eu quero usar sed para substituir 1.2.3.4 por outro ip.

Eu não sei como escrever o comando sed .

sed "s/oldip/newip/g"

Eu sei um pouco sobre a expressão regular, mas isso parece ser muito difícil para mim.

Obrigado.

    
por NingLee 01.11.2014 / 10:51

2 respostas

1

Se você usa um sed moderno, o seguinte funciona:

sed -e 's/\(^\|[^0-9]\)1\.2\.3\.4\($\|[^0-9]\)/NEWIP/'

Ou seja, substitua 1.2.3.4 por NEWIP , se no início da linha ou precedido por um não dígito, e se adicionalmente no final da linha ou seguido por um não dígito.

Com uma versão antiga sed que não suporta regexps estendidos, é mais complicado. Você pode fazer isso, por exemplo, usando caracteres de marcação. Precisamos de dois caracteres com garantia de não ocorrerem na entrada. Na solução abaixo, eu uso , e : aqui, mas qualquer outro caractere serve, até mesmo caracteres de controle.

sed -e 's/\(1\.2\.3\.4\)/,:/;s/\([0-9]\),//;s/:\([0-9]\)//;s/,.*:/NEWIP/;s/[,:]//'

Primeiro, inserimos , antes e : após o padrão que queremos substituir; em seguida, excluímos , se precedido por um dígito e : se seguido por um dígito; então substituímos a string de , to : (se ainda estiver presente) pela string de substituição; finalmente, excluímos qualquer , ou : restante.

Com o perl, também é possível usar uma asserção de look-ahead negativo (?!\d) e uma asserção negativa de look-behind (?<!\d) para garantir que o padrão corresponda apenas se não precedido ou seguido por um dígito:

perl -pe 's/(?<!\d)1\.2\.3\.4(?!\d)/NEWIP/;'
    
por 01.11.2014 / 12:50
1

Você não disse o que deseja fazer com as linhas que não contêm um IP válido, portanto, suponho que você queira ignorá-las. Então, tudo o que você precisa fazer é garantir que a linha inteira corresponda a três grupos de um a três números ( [0-9]{1,3} ) e, em seguida, um grupo final de um a três números. Aqui estão três maneiras de fazer isso:

  • GNU sed

    sed -r 's/^([0-9]{1,3}\.){3}[0-9]{1,3}$/5.6.7.8/' file
    
  • Não-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
    
por 01.11.2014 / 16:04