Extrai informações pelo awk e sed

3

Eu quero extrair o ip muito próximo a (axyz-pc) . Eu fiz essa tarefa através do comando grep usando regex. Mas eu preciso extrair pelo awk e sed. grep -Po '(?<='axyz-pc')[^:]+' logs | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'| sort -nr| uniq -c |sort -nr

Logs:

2017-04-11 15:15:00 SMTP connection from (axyz-pc) [36.32.138.106]:1236 I=[10.10.19.36]:25 closed by DROP in ACL
2017-04-11 15:15:01 H=(axyz-pc) [114.225.87.41]:3823 I=[10.10.19.36]:25 rejected EHLO or HELO axyz-pc: HELO/EHLO - HELO on heloblocks Blocklist
2017-04-11 15:15:01 SMTP connection from (axyz-pc) [114.225.87.41]:3823 I=[10.10.19.36]:25 closed by DROP in ACL
2017-04-11 15:15:02 H=(axyz-pc) [36.32.138.216]:1984 I=[10.10.19.36]:25 rejected EHLO or HELO axyz-pc: HELO/EHLO - HELO on heloblocks Blocklist
2017-04-11 15:15:02 SMTP connection from (axyz-pc) [36.32.138.216]:1984 I=[10.10.19.36]:25 closed by DROP in ACL
2017-04-11 15:15:02 H=(axyz-pc) [37.49.224.14]:51593 I=[10.10.19.36]:25 rejected EHLO or HELO axyz-pc: HELO/EHLO - HELO on heloblocks Blocklist
2017-04-11 15:15:02 SMTP connection from (axyz-pc) [37.49.224.14]:51593 I=[10.10.19.36]:25 closed by DROP in ACL
2017-04-11 15:15:02 H=(axyz-pc) [36.32.138.106]:4619 I=[10.10.19.36]:25 rejected EHLO or HELO axyz-pc: HELO/EHLO - HELO on heloblocks Blocklist

A saída deve ser (ip duplicado e não repetição):

36.32.138.106
114.225.87.41
36.32.138.216
37.49.224.14
    
por blaCkninJa 11.04.2017 / 12:51

5 respostas

2

Não sei por que grep fica preso, você terá que explorar isso ainda mais. No entanto, não há necessidade de perlre aqui, algo assim faria (pelo menos para a amostra que você deu):

grep -o 'axyz-pc) \[[^]]*' | grep -o '[^[]*$'

Saída:

36.32.138.106
114.225.87.41
114.225.87.41
36.32.138.216
36.32.138.216
37.49.224.14
37.49.224.14
36.32.138.106

Agora, classifique numericamente e aplique uniq :

sort -t. -k1,1n -k2,2n -k3,3n -k4,4n | uniq

Saída:

36.32.138.106                                                             
36.32.138.216
37.49.224.14
114.225.87.41
    
por 11.04.2017 / 13:15
2

Se você precisar usar sed , supondo que o ip esteja entre os primeiros colchetes:

sed -n '/axyz-pc/s/[^[]*\[\([0-9.]*\).*//p' x|sort -nr| uniq
    
por 11.04.2017 / 13:28
2

usando o awk e informando que os campos estão separados por ] ou [ e que precisamos apenas do segundo campo:

awk -F'[][]'  '
     {uniqoccurences[$2]++;}
 END { for (i in uniqoccurences) {
            print i ":" uniqoccurences[i] 
        } 
     } '

No exemplo acima, também imprimo ": n", ou seja, o número de ocorrências de cada "$ 2", mas não há necessidade de fazer isso (nesse caso, basta fazer print i no loop dentro do END section)

O regexp: [][] está usando a maneira como regexp trata ] e [ dentro de uma classe de caractere [...] ( ] depois que [ é tratado como um caractere para procurar, e um [ após o [ inicial (e antes de um ] de fechamento) também é tratado como um caractere para procurar. Portanto, [][] procura por ] ou [ )

Outra maneira:

awk -F'[][]'  '{ print $2 }' | sort | uniq
    
por 11.04.2017 / 13:37
2

Algumas opções:

  1. GNU grep

    $ grep -oP '\(axyz-pc\) \[\K[^]]+' file | sort | uniq 
    114.225.87.41
    36.32.138.106
    36.32.138.216
    37.49.224.14
    
  2. perl

    $ perl -lne '/\(axyz-pc\) \[([^]]+)/ && ++$seen{$1}<2 && print $1' file 
    36.32.138.106
    114.225.87.41
    36.32.138.216
    37.49.224.14
    
  3. awk

    $ awk -F ') \[' '{print $2}' file | awk -F '\]' '!seen[$1]++{print $1}'
    36.32.138.106
    114.225.87.41
    36.32.138.216
    37.49.224.14
    
  4. sed

    $ sed -n 's/.*(axyz-pc) \[\([^]]*\).*//p' file | sort | uniq
    114.225.87.41
    36.32.138.106
    36.32.138.216
    37.49.224.14
    
por 11.04.2017 / 13:44
1
cat in.txt | awk '/SMTP/{print $7}'  

me dá isso.

[36.32.138.106]:1236
[114.225.87.41]:3823
[36.32.138.216]:1984
[37.49.224.14]:51593

Para o passo final:

cat in.txt | awk '/SMTP/{print $7}' | sed -e 's/\[//; s/\]//; s/:...//' 

Editar: Os $ 7 acima não funcionarão porque os dois tipos de linhas têm diferentes desvios de campo para o endereço IP. Uma maneira melhor poderia ser:

cat in.txt | awk -F "axyz-pc\) \[" '{print $2}' | awk -F"\]" '{print $1}'

Nós usaríamos "axyz-pc" como o delimitador de campo no primeiro awk, em seguida, canalizássemos a saída para o segundo awk.

Usando sed em vez disso, não seria complicado.

    
por 11.04.2017 / 20:09