Broネットワークログ解析スクリプトを最適化するのに役立ちます。背景は次のとおりです。
私は多数の兄弟ログを持っていますが、私の範囲(複数可変長サブネット)のIPを照会することにのみ興味があります。
したがって、私が探しているIP範囲に一致する正規表現パターンを含むテキストファイルがあります。
/^10\.0\.0\.([8-9]|[1-3][0-9]|4[0-5])$/
(scope.txtには、正規表現パターンの追加IP範囲の最大20行が含まれています。)findInScope.sh:
#!bin/sh
for file in /data/bro_logs/2016-11-26/conn.*.log.gz
do
echo "$file"
touch /tmp/$file
for nets in $(cat scope.txt)
do
echo "$nets"
zcat $file | bro-cut -d | awk '$3 ~ '$nets' || $5 ~ '$nets'' >> /tmp/$file
done
sort /tmp/$file | uniq > ~/$file
rm /tmp/$file
done
追加の背景知識として、生のbro connログは1時間あたり約100MBであるため、現在のスクリプトは1時間分のログデータを解析するのに約10〜20分かかります。 1日の記録には最大3時間かかることがあります。
私は40個の単一のawkステートメントを使用することを検討しましたが、別のIP範囲で同じスクリプトを使用できるように別のscope.txtファイルが必要だったので、そうしないことにしました。
また、複数のconn.logファイル(zcat conn.*.log.gzなど)でzcatを試みましたが、出力ファイルが1 GBを超えて時間ごとのログを残したかったのです。
答え1
awkを介してログファイルを一度だけ渡すと、多くの利点が得られます。これは、すべての正規表現を1つにまとめることを意味します。scope.txt
ファイルでこれをしたくない場合は、awkを呼び出す前に実行してください。例えば、
sed <scope.txt 's|^/\^|(|; s|\$/$|)|; $!s/$/|/' | tr -d '\n' >pattern
zcat $file | bro-cut -d |
awk '
BEGIN{ getline pat <"pattern"; pat = "^(" pat ")$" }
$3 ~ pat || $5 ~ pat
' >~/$file
sed は、各正規表現行の周りの合計を閉じるペアに/^
置き換え、行の末尾に 1 を追加し、1 行の結果をすべてファイルに保存します。したがって、ファイルはすべてORで連結されたパターンです。欠落しているコンテンツは、スキーマファイルを変数として読み取るawkスクリプトステートメントに追加されます。$
()
|
pattern
^(...)$
BEGIN
pat
上記は内部for
ループを置き換えますsort|uniq
。
答え2
scope.txt
最も簡単な答えは、わずかに変更されたファイルをスキーマファイルとして使用しzcat | grep
(または単にzgrep
)を使用して必要な行を取得することです。
まず、scope
ファイルを変更して次を変更します。
/^10\.0\.0\.([8-9]|[1-3][0-9]|4[0-5])$/
入力する:
(^|[^0-9.])(10\.0\.0\.([8-9]|[1-3][0-9]|4[0-5]))($|[^0-9.])
これを簡単に実行するには、次のものを使用できます。
sed -e 's:^/\^:(^|[^0-9.])(:' -e 's:\$/$:)($|[^0-9.]):' scope.txt > grepscope.txt
次に、次を検索してください。
zgrep -Ehf grepscope.txt /data/bro_logs/2016-11-26/conn.*.log.gz | less
または、各ファイルの出力を別々に保存したいので:
for f in /data/bro_logs/2016-11-26/conn.*.log.gz; do
zgrep -Ehf grepscope.txt "$f" | sort -u > ~/"${f##*/}"
done
また、「for」ループ変数には以下が$f
含まれます。みんな各ファイルのパスを順番に指定します。~/"$f"
(存在しない可能性があるホームディレクトリのサブディレクトリを参照する)出力を指示するときにエラーを防ぐために、パス名から最後のスラッシュの前のすべてのエントリを~/data/bro_logs/2016-11-26
削除し、デフォルト名のみを使用します。各ログファイル。
言及する兆候zgrep
:
-E
パターンの括弧をエスケープする必要がないように拡張正規表現を指定します。
-h
一致する各行のプレフィックスでファイル名を印刷しません。 (for
ループバージョンではこのオプションを省略できます。デフォルトでは、最初に指定したコマンドと同じように複数のgrep
ファイルを検索するときにファイル名のみを印刷しますが、両方のバージョンにそのまま残しても破損は発生しません。)
-f
できるようにスキーマファイルを指定します。 あなたの質問によると、これはあなたに必要なものであり、あなたは多くのgrep -f
"or"を含むAwkコマンドを書く必要なしにファイルから取得した複数の検索パターンを使うことができます。
sort | uniq
特定のオプションフラグをsort -u
使用する必要がない限り、通常は置き換えることができます。uniq
この場合はそれを必要としないので、より単純な形式を使用しましたsort -u
。