在 awk 中匹配字符串

在 awk 中匹配字符串

我如何搜索文件以找到包含 SRC= 的行,例如这里?我的意思是,例如,如何使用 awk 在此文件中查找源 IP 地址

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

谢谢你们! :)

答案1

不幸的是,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

答案2

虽然使用 awk 肯定可以做到这一点,但使用 grep 则更直接:

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

怎么运行的:

  • -P启用Perl 兼容正则表达式

  • -o仅显示该行匹配的部分。

  • (?<=SRC=)是一个积极的后视断言,即匹配之前必须有SRC=

  • [\d.]+是任意数量的数字和点。

答案3

sed 解决方案(sed 与 UNIX 系统中的 awk 一样标准):

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

它的作用是尝试删除 a 之前SRC=和下一个空格之后的所有内容。替换完成后,打印结果行。如果 ip 地址是行的最后一个字段,则需要进行第二次替换。

答案4

即使字段数量发生变化,此方法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

相关内容