grep和打印反向引用(Grep and print back reference)

2019-08-17 03:40发布

我有这样的iptable日志:

Feb 25 10:32:48 XXX: [414645.555838] FW: DEN TCP IN=eth0 OUT= MAC=XYZ SRC=1.1.1.1 DST=2.2.2.2 LEN=40 TOS=0x00 PREC=0x00 TTL=57 ID=0 DF PROTO=TCP SPT=80 DPT=51814 WINDOW=0 RES=0x00 RST URGP=0

我希望到grep 1.1.1.1和80(SRC和SPT场)。 我这样做:

grep -oP 'SRC=([^ ]+).+SPT=([0-9]+)' /var/log/iptables.log

但它返回:

SRC=1.1.1.1 DST=2.2.2.2 LEN=40 TOS=0x00 PREC=0x00 TTL=57 ID=0 DF PROTO=TCP SPT=80

如何获得$ 1和$ 2只(参照匹配值)?

Answer 1:

一个sed方法:

sed -rn 's/.*SRC=([^ ]+).*SPT=([0-9]+).*/\1 \2/p' /var/log/iptables.log

可以通过管道将它while read src spt在脚本或类似的东西。 现在,这当然不是很有效,因为三星星的图案,因此,如果性能是一个问题,你可以考虑使用类似的东西cut中提取的某些字段:

cut -d' ' -f12,21 /var/log/iptables.log

不知道,如果记录格式是一致的就好了这个工作。



Answer 2:

你的榜样的主要问题是,你试图返回分组,这是不可能的IIUC。 解决此问题的方法是使用正向后看(见man perlre ):

grep -oP '(?<=SRC=|SPT=)[^ ]*'

输出:

1.1.1.1
80

这里有一个更便携的选择:

grep -o 'SRC=[^ ]*\|SPT=[^ ]*' | grep -o '[^=]*$'

如果您所要的输出在同一行,你应该考虑去一个工具了,即使用利的回答。 如果您知道的输出总是成对出现,你可以加入与线paste

grep -oP '(?<=SRC=|SPT=)[^ ]*' | paste - -

或与xargs

grep -oP '(?<=SRC=|SPT=)[^ ]*' | xargs -n2

sed

grep -oP '(?<=SRC=|SPT=)[^ ]*' | sed 'N; s/\n/ /'


文章来源: Grep and print back reference