Извлечение информации через awk и sed

Извлечение информации через awk и sed

Я хочу извлечь ip, который находится совсем рядом с (axyz-pc). Я сделал эту задачу через grepкоманду с использованием regex. Но мне нужно извлечь через awk и 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

Журналы:

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

Вывод должен быть таким (дублирующийся IP не повторяется):

36.32.138.106
114.225.87.41
36.32.138.216
37.49.224.14

решение1

Я не уверен, почему grepзастревает, вам придется исследовать это дальше. Однако здесь нет необходимости в perlre, что-то вроде этого подойдет (по крайней мере, для примера, который вы привели):

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

Выход:

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

Теперь отсортируйте по числам и примените uniq:

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

Выход:

36.32.138.106                                                             
36.32.138.216
37.49.224.14
114.225.87.41

решение2

Если вам нужно использовать sed, предполагая, что IP находится в первых скобках:

sed -n '/axyz-pc/s/[^[]*\[\([0-9.]*\).*/\1/p' x|sort -nr| uniq

решение3

используя awk, и сообщая ему, что поля разделены с помощью ]or [и что нам нужно только второе поле:

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

В приведенном выше примере я также вывожу «:n», т.е. количество вхождений каждого «$2», но в этом нет необходимости (в этом случае просто сделайте это print iв цикле внутри ENDраздела)

Регулярное выражение: [][]использует способ, которым регулярное выражение обрабатывает ]и [внутри [...]класса символов (a ]сразу после a [затем рассматривается как символ для поиска, и a [после начальной [(и перед закрывающей ]) также рассматривается как символ для поиска. Поэтому [][]ищет ]или [)

Другой путь:

awk -F'[][]'  '{ print $2 }' | sort | uniq

решение4

cat in.txt | awk '/SMTP/{print $7}'  

дает мне это.

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

Для последнего шага:

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

Редактировать: Вышеуказанный $7 не будет работать, поскольку два типа строк имеют разные смещения полей для IP-адреса. Лучший способ может быть таким:

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

Мы бы использовали «axyz-pc» в качестве разделителя полей в первом awk, а затем передали бы вывод во второй awk.

Использовать вместо этого sed не составит труда.

Связанный контент