我有这样的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只(参照匹配值)?
一个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
不知道,如果记录格式是一致的就好了这个工作。
你的榜样的主要问题是,你试图返回分组,这是不可能的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/ /'