1

Как я могу найти файл, чтобы найти строки с SRC =, например, здесь? я имею в виду, как я могу найти исходный IP-адрес в этом файле, например, с помощью awk

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

и тогда я хотел бы получить этот вывод:

192.168.1.28
192.168.1.30
192.168.1.31
192.168.1.32

Есть много строк (100 000), и я хочу найти SRC =, а затем, когда я найду строки, обрезать SRC = и просто найти IP-адрес

ИСПОЛЬЗУЯ AWK

Спасибо вам всем! :)

6 ответов6

4

К сожалению, awk не захватывает свои группы. Возможно, вы захотите найти более современный инструмент для написания однострочников, такой как Perl.

При этом самый быстрый способ сделать это в вашем случае зависит от того, всегда ли SRC = находится в одном и том же месте в журналах.

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

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

В противном случае для более надежного подхода вы можете заменить часть, ведущую к SRC =, и часть, следующую за ней:

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

Если вам нужно сосчитать вхождения, вы можете добавить идиоматический | sort | uniq -c | sort -rn в конвейер, но это неэффективно с 100 000 строк. Вам лучше использовать встроенный словарь awk для первых двух шагов:

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

Вывод любого из них должен выглядеть следующим образом:

7513  192.168.1.28
 330  192.168.1.30
 103  192.168.1.31
  19  192.168.1.32
3

Хотя это, конечно, возможно с awk, с grep это гораздо проще:

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

Как это устроено:

  • -P включает Perl-совместимые регулярные выражения.

  • -o отображает только совпадающую часть линии.

  • (?<=SRC=) является положительным подтверждением, то есть сопоставлению должно предшествовать SRC =.

  • [\d.]+ - любое количество цифр и точек.

2

Этот чистый awk работает, даже если количество полей изменяется, если перед желаемым IP стоит SRC= а затем пробел:

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

Это может быть проще с gawk который имеет функцию match() которая позволяет вам захватывать шаблоны:

gawk 'match($0,/SRC=([0-9.]+)/,k){print k[1]}' a
2

Решение sed (sed стандартно как awk в системах UNIX):

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

Он пытается удалить все до SRC= и после следующего пробела. Когда замена сделана, выведите полученную строку. Вторая замена необходима, если IP-адрес является последним полем строки.

2

Я бы сделал это с помощью awk:

awk -F '[ =]' '{for (i=1; i<NF; i++) if ($i == "SRC") {print $(i+1); next}}'
1

Еще один awk чтобы попробовать, который отбрасывает строки, которые не содержат SRC=:

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

Или попробуйте другой sed:

sed -n '/.*SRC=/{s///; s/ .*//p;}' file

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .