w00*_*00d 3 bash shell grep iptables
我有这个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
Run Code Online (Sandbox Code Playgroud)
我想grep 1.1.1.1和80(SRC和SPT字段).我这样做:
grep -oP 'SRC=([^ ]+).+SPT=([0-9]+)' /var/log/iptables.log
Run Code Online (Sandbox Code Playgroud)
但它返回:
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
Run Code Online (Sandbox Code Playgroud)
如何获得$ 1和$ 2(参考匹配值)?
一种sed
做法:
sed -rn 's/.*SRC=([^ ]+).*SPT=([0-9]+).*/\1 \2/p' /var/log/iptables.log
Run Code Online (Sandbox Code Playgroud)
您可以将其通过管道传输到while read src spt
脚本或类似内容中。现在这当然不是很有效,因为模式中的三颗星,所以如果性能是一个问题,你可以考虑使用诸如cut
提取某些字段之类的东西:
cut -d' ' -f12,21 /var/log/iptables.log
Run Code Online (Sandbox Code Playgroud)
不确定日志格式是否足够一致以使其正常工作。
你的例子的主要问题是你试图返回分组,这是不可能的IIUC.解决这个问题的一种方法是使用积极的后视(见man perlre
):
grep -oP '(?<=SRC=|SPT=)[^ ]*'
Run Code Online (Sandbox Code Playgroud)
输出:
1.1.1.1
80
Run Code Online (Sandbox Code Playgroud)
这是一个更便携的替代方案:
grep -o 'SRC=[^ ]*\|SPT=[^ ]*' | grep -o '[^=]*$'
Run Code Online (Sandbox Code Playgroud)
如果你想让输出在一行上,你应该考虑使用一个工具,即使用Lev的答案.如果你知道输出总是成对出现,你可以加入以下行paste
:
grep -oP '(?<=SRC=|SPT=)[^ ]*' | paste - -
Run Code Online (Sandbox Code Playgroud)
或者xargs
:
grep -oP '(?<=SRC=|SPT=)[^ ]*' | xargs -n2
Run Code Online (Sandbox Code Playgroud)
或者sed
:
grep -oP '(?<=SRC=|SPT=)[^ ]*' | sed 'N; s/\n/ /'
Run Code Online (Sandbox Code Playgroud)