Eu quero extrair o ip ao lado de (axyz-pc)
. Eu fiz esta tarefa através de grep
comando usando regex. Mas preciso extrair através do awk e do 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
Histórico:
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, não repetido):
36.32.138.106
114.225.87.41
36.32.138.216
37.49.224.14
Responder1
Não sei por que grep
ficou preso, você terá que explorar isso mais a fundo. No entanto, não há necessidade de perlre aqui, algo assim serviria (pelo menos para a amostra que você forneceu):
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
Responder2
Se precisar usar sed
, supondo que o ip esteja entre colchetes:
sed -n '/axyz-pc/s/[^[]*\[\([0-9.]*\).*/\1/p' x|sort -nr| uniq
Responder3
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 da END
seção)
O regexp: [][]
está usando a forma como o regexp trata ]
e [
dentro de uma [...]
classe de caractere (a ]
logo após a [
é então tratado como um caractere a ser procurado, e a [
após o inicial [
(e antes de um fechamento ]
) também é tratado como um caractere a ser procurado. Então [][]
procura ]
ou [
)
Outra maneira:
awk -F'[][]' '{ print $2 }' | sort | uniq
Responder4
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 a etapa 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 deslocamentos de campo diferentes para o endereço IP. Uma maneira melhor poderia ser:
cat in.txt | awk -F "axyz-pc\) \[" '{print $2}' | awk -F"\]" '{print $1}'
Usaríamos "axyz-pc" como delimitador de campo no primeiro awk e depois canalizaríamos a saída para o segundo awk.
Usar sed em vez disso não seria complicado.