4

この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

1.1.1.1 と 80 (SRC と SPT フィールド) を grep したい。私はこれをします:

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 のみを取得するにはどうすればよいですか (一致した値への参照)。

4

2 に答える 2

10

あなたの例の主な問題は、グループ化を返そうとしていることです.これはIIUCでは不可能です. これを回避する 1 つの方法は、肯定的な後読みを使用することです ( を参照man perlre)。

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

出力:

1.1.1.1
80

より移植性の高い代替手段を次に示します。

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

出力を 1 行にしたい場合は、ツールを 1 つ上に移動することを検討する必要があります。つまり、Lev の回答を使用します。出力が常にペアになることがわかっている場合は、次のように行を結合できますpaste

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

またはxargs

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

またはsed:

grep -oP '(?<=SRC=|SPT=)[^ ]*' | sed 'N; s/\n/ /'
于 2013-02-25T13:47:34.167 に答える
8

sedアプローチ:

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

while read src sptスクリプトまたは同様のものにパイプできます。もちろん、これはあまり効率的ではありません。パターンに 3 つの星があるためです。したがって、パフォーマンスが問題になる場合は、cut特定のフィールドを抽出するようなものを使用することを検討できます。

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

これが機能するのにログ形式が十分に一貫しているかどうかはわかりません。

于 2013-02-25T13:18:48.907 に答える