access.log
パターンがある各行に対して、次の操作を行います/mypattern
。
www.example.com:80 192.0.2.17 - - [29/Sep/2017:13:49:02 +0200] "GET /mypattern?foo=bar&iptosearch=198.51.100.5
iptosearch
パラメータを抽出し、そのIPを持つすべての行を表示したいと思います。access.log
そして含まれていますblah
。例:
[29/Sep/2017:13:49:02 +0200] "GET /mypattern?foo=bar&iptosearch=198.51.100.5:
www.example3.com:80 198.51.100.5 - - [27/Sep/2017:00:00:00 +0200] "GET /hello/blah" ...
www.example2.com:80 198.51.100.5 - - [25/Sep/2017:00:00:00 +0200] "GET /blah.html" ...
www.example7.com:80 198.51.100.5 - - [12/Sep/2017:00:00:00 +0200] "GET /index.htm?i=blah" ...
[27/Sep/2017:00:00:00 +0200] "GET /mypattern?iptosearch=203.0.113.2&foo2=bar5:
www.example32.com:80 203.0.113.2 - - [15/Sep/2017:00:00:00 +0200] "GET /hello/blah" ...
www.example215.com:80 203.0.113.2 - - [14/Sep/2017:00:00:00 +0200] "GET /blah.html" ...
私はこれをしようとしています:
grep -f <(grep -o 'mypattern.*iptosearch=(.*)' access.log) access.log |grep blah
しかし:
前の例のように並べ替えられないことがあります。タイトルと下のリストは関連項目に対応しています。
iptosearch
私の例のタイトル()には、
[29/Sep/2017:13:49:02 +0200] "GET /test?foo=bar&iptosearch=198.51.100.5:
次の内容が含まれていないため表示されません。blah
以前のように表示するにはどうすればよいですか?この場合、ループを使用する必要がありますか?
答え1
拡大する強く打つ+grep+アッ方法:
サンプルaccess.log
コンテンツ:
www.example3.com:80 198.51.100.5 - - [27/Sep/2017:00:00:00 +0200] "GET /hello/blah" ...
www.example2.com:80 198.51.100.5 - - [25/Sep/2017:00:00:00 +0200] "GET /blah.html" ...
[29/Sep/2017:13:49:02 +0200] "GET /mypattern?foo=bar&iptosearch=198.51.100.5:
www.example7.com:80 198.51.100.5 - - [12/Sep/2017:00:00:00 +0200] "GET /index.htm?i=blah" ...
www.example32.com:80 203.0.113.2 - - [15/Sep/2017:00:00:00 +0200] "GET /hello/blah" ...
[27/Sep/2017:00:00:00 +0200] "GET /mypattern?iptosearch=203.0.113.2&foo2=bar5:
www.example215.com:80 203.0.113.2 - - [14/Sep/2017:00:00:00 +0200] "GET /blah.html" ...
働く:
grep '/mypattern' access.log | while read -r l; do
if [[ $l =~ iptosearch=(([0-9]+\.){3}[0-9]+) ]]; then
echo "$l"
awk -v ip="${BASH_REMATCH[1]}" '$0~ip && /blah/;END{ print "" }' access.log
fi
done
出力:
[29/Sep/2017:13:49:02 +0200] "GET /mypattern?foo=bar&iptosearch=198.51.100.5:
www.example3.com:80 198.51.100.5 - - [27/Sep/2017:00:00:00 +0200] "GET /hello/blah" ...
www.example2.com:80 198.51.100.5 - - [25/Sep/2017:00:00:00 +0200] "GET /blah.html" ...
www.example7.com:80 198.51.100.5 - - [12/Sep/2017:00:00:00 +0200] "GET /index.htm?i=blah" ...
[27/Sep/2017:00:00:00 +0200] "GET /mypattern?iptosearch=203.0.113.2&foo2=bar5:
www.example32.com:80 203.0.113.2 - - [15/Sep/2017:00:00:00 +0200] "GET /hello/blah" ...
www.example215.com:80 203.0.113.2 - - [14/Sep/2017:00:00:00 +0200] "GET /blah.html" ...
詳細:
while read -r l ...
/mypattern
- コマンドから返された行を繰り返します。grep
[[ $l =~ iptosearch=(([0-9]+\.){3}[0-9]+) ]]
- 各行を正規$l
表現と一致させますiptosearch=(([0-9]+\.){3}[0-9]+)
。 ""二項演算子によって条件付きコマンドに
BASH_REMATCH
メンバーが割り当てられた配列変数。インデックス付きの要素は、正規表現全体に一致する文字列部分です。インデックス付きの要素は、最初の角かっこ内のサブ式と一致する文字列部分です。この変数は読み取り専用です。=~
[[
0
n
n
(...)
-v ip="${BASH_REMATCH[1]}"
- 変数を渡しますip
。アッスクリプト$0~ip && /blah/
-ip
現在の値とキーワードを含む出力ラインのみblah
答え2
awk '/blah/ && $2 == "198.51.100.5" { print }' access.log
blahというテキストを含むすべての行を検索します。 2番目のスペースで区切られたフィールドも「198.51.100.5」の場合は、その行を印刷します。