string de correspondência no awk

1

Como posso pesquisar o arquivo para encontrar as linhas que têm SRC =, por exemplo, aqui? Quero dizer, como posso encontrar o endereço IP de origem neste arquivo usando o awk, por exemplo

Mar 10 03:17:12 ubuntu kernel: [11045.721649] Type=ScanXMASIN=eth0 OUT= MAC=00:0c:29:a1:51:1c:00:0c:29:23:9d:e4:08:00 SRC=192.168.1.28 DST=192.168.1.27 LEN=40 TOS=0x00 PREC=0x00 TTL=47 ID=6603 PROTO=TCP SPT=47301 DPT=53 WINDOW=1024 RES=0x00 URG PSH FIN URGP=0 
Mar 10 03:17:12 ubuntu kernel: [11045.721702] Type=ScanXMASIN=eth0 OUT= MAC=00:0c:29:a1:51:1c:00:0c:29:23:9d:e4:08:00 SRC=192.168.1.30 DST=192.168.1.27 LEN=40 TOS=0x00 PREC=0x00 TTL=42 ID=6802 PROTO=TCP SPT=47301 DPT=5900 WINDOW=1024 RES=0x00 URG PSH FIN URGP=0 
Mar 10 03:17:32 ubuntu kernel: [11065.703937] Type=ScanACKIN=eth0 OUT= MAC=00:0c:29:a1:51:1c:00:0c:29:23:9d:e4:08:00 SRC=192.168.1.31 DST=192.168.1.27 LEN=40 TOS=0x00 PREC=0x00 TTL=40 ID=62992 PROTO=TCP SPT=47301 DPT=1521 WINDOW=1024 RES=0x00 URG PSH FIN URGP=0 
Mar 10 03:17:32 ubuntu kernel: [11065.706729] Type=ScanXMASIN=eth0 OUT= MAC=00:0c:29:a1:51:1c:00:0c:29:23:9d:e4:08:00 SRC=192.168.1.32 DST=192.168.1.27 LEN=40 TOS=0x00 PREC=0x00 TTL=47 ID=15170 PROTO=TCP SPT=47301 DPT=14442 WINDOW=1024 RES=0x00 URG PSH FIN URGP=0

e depois gostaria de obter esta saída:

192.168.1.28
192.168.1.30
192.168.1.31
192.168.1.32

Existem muitas linhas (100.000) e eu quero procurar por SRC = e, em seguida, quando eu encontrar linhas de corte SRC = e apenas encontrar o endereço IP

USANDO o AWK

obrigada a todos! :)

    
por Arash 10.03.2013 / 12:03

6 respostas

4

Infelizmente o awk não captura seus grupos. Você pode querer procurar uma ferramenta mais moderna para escrever frases de efeito, como Perl.

Dito isto, a maneira mais rápida de fazer isso no seu caso depende se o SRC = está sempre no mesmo lugar nos logs.

Se ele estiver sempre no mesmo lugar e os argumentos sempre contiverem o mesmo número de sinais de igual, você pode dividir suas linhas em iguais e espaço e usar o 15º campo:

awk -F'[= ]' '{print $15}'

Caso contrário, para uma abordagem mais robusta, você pode substituir a parte que leva a SRC = e a parte seguinte:

awk '{sub(/.* SRC=/, ""); sub(/ .*/, ""); print;}'

Se você precisar contar as ocorrências, adicione um idiomático | sort | uniq -c | sort -rn ao pipeline, mas isso é ineficiente com 100.000 linhas. É melhor usar o tipo de dicionário interno do awk nas duas primeiras etapas:

awk '{sub(/.* SRC=/, ""); sub(/ .*/, ""); ips[$0]++;}
     END {for (ip in ips) printf("%8d  %s\n", ips[ip], ip);}' | sort -nr

A saída de um dos dois deve ficar assim:

7513  192.168.1.28
 330  192.168.1.30
 103  192.168.1.31
  19  192.168.1.32
    
por 10.03.2013 / 12:49
3

Embora isso seja certamente possível com o awk, é muito mais direto com o grep:

grep -Po "(?<=SRC=)[\d.]+"

Como funciona:

  • -P permite Expressões regulares compatíveis com Perl .

  • -o exibe apenas a parte correspondente da linha.

  • (?<=SRC=) é uma afirmação positiva, por exemplo, a correspondência deve ser precedida por SRC = .

  • [\d.]+ é qualquer número de dígitos e pontos.

por 10.03.2013 / 13:06
2

Uma solução sed (sed é padrão como awk em sistemas UNIX):

sed -n -e 's/.*SRC=\([^ ]*\).*//p' -e 's/.*SRC=\([^ ]*\)$//p' file

O que ele faz é tentar remover tudo antes de um SRC= e depois do próximo espaço. Quando uma substituição é feita, imprima a linha resultante. A segunda substituição é necessária se o endereço IP for o último campo da linha.

    
por 10.03.2013 / 13:50
2

Eu faria isso com o awk:

awk -F '[ =]' '{for (i=1; i<NF; i++) if ($i == "SRC") {print $(i+1); next}}'
    
por 10.03.2013 / 16:49
2

Esse awk puro funciona mesmo se o número de campos mudar, desde que o IP desejado seja precedido por SRC= e seguido por um espaço:

awk -F'SRC=' '{print $2}' a | awk '{print $1}'

Isso pode ser mais direto com gawk , que tem a função match() , que permite capturar padrões:

gawk 'match($0,/SRC=([0-9.]+)/,k){print k[1]}' a
    
por 11.03.2013 / 00:47
1

Ainda outro awk para tentar descartar as linhas que não contêm SRC= :

awk -F'.*SRC=| ' '/SRC=/{print $2}' file

Ou tente outro sed :

sed -n '/.*SRC=/{s///; s/ .*//p;}' file
    
por 11.03.2013 / 02:04

Tags