Expressão regular para localizar IP de remetente usando grep ou outras linguagens

0

Eu tenho um arquivo de entrada que contém:

19:04:01.631948 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)
181.173.82.61.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=active group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=120 auth="vlan72^@^@"
19:04:02.061482 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)

181.173.82.60.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=standby group=72      addr=171.64.72.1 hellotime=2s holdtime=7s priority=100 auth="vlan72^@^@"
19:04:03.583896 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)

181.173.82.61.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=active group=72  addr=171.64.72.1 hellotime=2s holdtime=7s priority=120 auth="vlan72^@^@"
19:04:04.005483 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)
181.173.82.60.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=standby group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=100 auth="vlan72^@^@"
19:04:05.511947 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)
181.173.82.61.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=active group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=120 auth="vlan72^@^@"
19:04:05.997361 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)

181.173.82.60.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=standby group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=100 auth="vlan72^@^@"
19:04:07.427876 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)

181.173.82.61.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=active group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=120 auth="vlan72^@^@"
19:04:07.925385 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)

181.173.82.60.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=standby group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=100 auth="vlan72^@^@"
19:04:09.403864 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)

181.173.82.61.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=active group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=120 auth="vlan72^@^@"
19:04:09.845241 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)

181.173.82.60.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=standby group=72   addr=171.64.72.1 hellotime=2s holdtime=7s priority=100 auth="vlan72^@^@"
19:04:10.877531 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto IGMP (2), length 28)

e eu quero que a saída seja assim:

181.173.82.61
and other ips
(just senders IP (left IP))

Eu tentei a seguinte expressão regular no grep:

grep -E -o '[1-9][0-9][0-9]?\.[1-9][0-9][0-9]?\.[0-9][0-9][0-9]?\.[0-9][0-9][0-9]?\.\s\>

Para resolver este problema, tento verificar os IPs ehit este formato:

(ip)(port)(space)(>)

e depois sed e excluir o > e números de porta mas a minha dose regular não funciona.
Eu apreciarei quaisquer outras formas, como awk ou melhores expressões regulares.

    
por Arash 23.04.2013 / 15:30

5 respostas

1

Se tudo o que você quer é o primeiro IP de cada linha, você pode fazer isso:

grep '>' file.txt | gawk '{print $1}' | cut -d "." -f -4

Saída no seu arquivo de exemplo:

181.173.82.61
181.173.82.60
181.173.82.61
181.173.82.60
181.173.82.61
181.173.82.60
181.173.82.61
181.173.82.60
181.173.82.61
181.173.82.60

Explicação:

  • grep '>' file.txt : imprime apenas as linhas que contêm o caractere > . No arquivo que você publicou, estas são as linhas que começam com um IP.

    grep '>' file.txt | head -1
    181.173.82.61.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=active group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=120 auth="vlan72^@^@"
    
  • gawk '{print $1}' : imprime o primeiro campo de cada linha.

      grep '>' file.txt | gawk '{print $1}' | head -1
      181.173.82.61.1985
    
  • cut -d "." -f -4 : use . como o delimitador de campo e imprima tudo até o quarto campo. Isso remove os números extras dos IPs.

    grep '>' file.txt | gawk '{print $1}' | cut -d "." -f -4 | head -1
    181.173.82.61
    
por 23.04.2013 / 18:52
1

No momento, sua expressão regular está procurando apenas um IP no formato xxx.xxx.xxx.xxx , mas os IPs podem ser x.x.x.x e qualquer coisa entre como xxx.xxx.x.xx (e, no seu exemplo: xxx.xxx.xx.xx para a parte IP) .

Então, isso significa que sua expressão regular precisa se parecer mais com:

'[1-9]{1,3}\.[0-9}{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,4} >'

Isso diz "Eu quero 1-9 em qualquer lugar de 1 a 3 seguidas, seguidas por '.', então 0-9 em qualquer lugar de 1-3 em uma linha", e assim por diante. Funciona para mim sem ? , FWIW.

Como você está dizendo explicitamente "espaço e >", não precisa ser muito extravagante.

    
por 23.04.2013 / 15:45
1

Tenho certeza que isso pode ser feito melhor do que isso, mas se eu copiar seu exemplo para um arquivo de teste e remover a marcação (os 4 espaços extras no início), então isso funciona:

>cat testfile | grep -E "[1-9]{1,3}\.[0-9}{1,3}\.[0-9]{1,3}\.[1-9]{1,3}" | cut -d. -f1-4

Saída apenas dos filtros do grep para:

181.173.82.61.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=active group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=120 auth="vlan72^@^@"
181.173.82.60.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=standby group=72      addr=171.64.72.1 hellotime=2s holdtime=7s priority=100 auth="vlan72^@^@"
181.173.82.61.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=active group=72  addr=171.64.72.1 hellotime=2s holdtime=7s priority=120 auth="vlan72^@^@"
181.173.82.60.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=standby group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=100 auth="vlan72^@^@"

Corte é usado para capturar apenas os primeiros quatro campos ( -f para o campo, 1-4 para 1,2,3,4), usando o ponto como -d eliminador).

    
por 23.04.2013 / 17:45
1

Usando seu arquivo de exemplo e um regex, cheguei a esta solução mais simples:

perl -ne 'print "$1\n" if /^(.*)\.\d+ >/' test.txt

Ele imprime todos os jogos antes de ". número da porta >"

    
por 24.04.2013 / 06:47
0

Estou bastante surpreso que ninguém tenha postado esta solução grep extremamente simples. Copiei e colei seu texto de amostra em um arquivo de texto chamado "ips.txt" e executei o seguinte comando:

grep -Eo "^([0-9]{1,3}\.){3}[^. ]*" ips.txt

A saída que recebi foi:

181.173.82.61
181.173.82.60
181.173.82.61
181.173.82.60
181.173.82.61
181.173.82.60
181.173.82.61
181.173.82.60
181.173.82.61
181.173.82.60

E se você quiser ver TODOS os IP_ADDRs no arquivo, apenas omita o ^ no início da expressão regular do comando grep. Ele exibirá todos os IPs em uma lista para você filtrar conforme desejado.

O que acontece é exatamente a mesma saída da resposta aceita, sem usar tantos canos. Contanto que o arquivo que precisa ser analisado contenha o remetente IP_ADDR no início da linha, esse comando fará o que você precisa.

    
por 12.01.2018 / 11:54