2013-02-25 42 views
3

我有這樣的iptable日誌:grep和打印恢復參照

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只(參照匹配值)?

回答

3

一個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 

不知道,如果日誌格式足夠一致的這個工作。

+0

感謝的sed解決方案,這工作。但我無法相信grep沒有這樣的功能。 – w00d 2013-02-25 13:31:43

+0

要以像grep一樣的方式使用sed,請使用:'sed -n's /.../.../ p'file',否則所有行將會是打印。 – potong 2013-02-25 17:10:25

+0

@potong你是對的,在這種情況下,我猜所有的線都匹配,但我仍然會編輯。謝謝 – 2013-02-25 18:04:42

7

你的例子的主要問題是你試圖返回分組,這是不可能的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/ /'