Я хочу извлечь 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 не составит труда.