pt - delete todos os dígitos na frente de cada ocorrência de um ponto

0

Estou tentando remover os dígitos na frente de alguns intervalos de IP abaixo:

range 1.1.1.10 1.1.1.100;

Eu quero exibir a seguinte saída:

IP range is: 10-100

Quando eu tento este comando:

echo '  range 1.1.1.10 1.1.1.100;' | sed -rn '/^\s*range/ s/.*\.([0-9]{1,3})\s*.*\.([0-9]{1,3});/IP range is: -/p'

Eu recebo:

IP range is: 1-100

Mas quando eu tento este comando

echo '  range 1.1.1.10 1.1.1.100;' | sed -rn '/^\s*range/ s/.*\.([0-9]{1,3})\s*.*([0-9]{1,3});/IP range is: -/p'

Eu recebo:

IP range is: 10-0

Estou faltando alguma coisa? Parece-me que sed não está procurando por um espaço imediatamente após o aparecimento do último octeto no primeiro endereço.

    
por Anoynmous 04.06.2018 / 20:31

4 respostas

1

Seu problema tem a ver com a ganância de .* . Você ainda pode fazer isso em sed , mas é mais fácil com o Perl:

$ echo 'range 1.1.1.10 1.1.1.100;' | perl -ne 'printf("IP range is %d-%d\n", (/\.(\d+)[^.]/g))'
IP range is 10-100

O script Perl corresponde aos números no final dos endereços IP e os retorna como dois inteiros que são usados em printf() para imprimir a string de saída formatada.

A expressão regular Perl

/\.(\d+)[^.]/g

irá capturar cada conjunto de dígitos precedido por um ponto, mas não seguido por um ponto.

Em sed você não precisa fazer a substituição de uma só vez:

$ echo 'range 1.1.1.10 1.1.1.100;' | sed -E -e 's/[^ ]*\.([0-9]+);//'
range 1.1.1.10 100

$ echo 'range 1.1.1.10 1.1.1.100;' | sed -E -e 's/[^ ]*\.([0-9]+);//' -e 's/[^ ]*\.([0-9]+) /-/'
range 10-100

$ echo 'range 1.1.1.10 1.1.1.100;' | sed -E -e 's/[^ ]*\.([0-9]+);//' -e 's/[^ ]*\.([0-9]+) /-/' -e 's/range/IP & is/'
IP range is 10-100

O script final sed :

s/[^ ]*\.([0-9]+);//;   # Isolate last number in range
s/[^ ]*\.([0-9]+) /-/;  # Isolate first number in range, add dash
s/range/IP & is/;         # Sort out text at start

Que, sob inspeção, pode ser encurtado para

s/[^ ]*\.([0-9]+)[^.]/-/g
s/range -/IP range is /

Isso é

$ echo 'range 1.1.1.10 1.1.1.100;' | sed -E -e 's/[^ ]*\.([0-9]+)[^.]/-/g' -e 's/range -/IP range is /'
IP range is 10-100
    
por 04.06.2018 / 21:52
1

Com gnuu sem controle da validade da linha

sed -E 's/.*\.(\S+)\s+.*\.(\S+);.*/IP range is: -/'
    
por 04.06.2018 / 22:34
0
sed -r '/^[[:blank:]]*range[[:blank:]]+/ {
    s///                 # delete the previous match, "range"
    s/;.*//
    s/[[:digit:]]+\.//g  # remove digits followed by dot
    s/[[:blank:]]+/-/
    s/^/IP range is: /
}' <<END
range 1.1.1.10 1.1.1.100;
END
IP range is: 10-100
    
por 04.06.2018 / 21:38
0
$ echo '   range 1.1.1.10 1.1.1.100;' |
  sed -Ene 's/^[[:blank:]]*range [0-9.]*\.([0-9]+) [0-9.]*\.([0-9]+);.*/IP range is: -/p'
IP range is: 10-100

em partes:

^[[:blank:]]*        any blanks at start of line
[0-9.]*\.            numbers and dots, ending with a dot 
([0-9]+)             capture the following numbers
[0-9.]*\.([0-9]+)    same, again
  and            put back the captured groups

s///p                print if the substitution matched 
    
por 04.06.2018 / 21:52