Shell Scriptで正規表現
shell スクリプトでファイルから1行ずつ読み込んだデータを正規表現を使って欲しい情報のみを別のファイルに書き出す 2 - xai1981's blog
を読んでいて、正規表現と言うとPerlを連想してしまうのですが、Shell Scriptでもできる!と知ったので(むしろ今までできることに気付かなかった)やってみました。
正規表現
expr "対象文字列" : "マッチさせるパターン"
マッチした位置や()でグループ化した結果を出力します。
今回はいらないので/dev/nullに捨てます。
http://qiita.com/Linda_pp/items/31fa611766598715a172
実行
使用したデータ、スクリプト、実行結果です。
やっていることは読んだ記事とほぼ同じですので、ご興味がありましたら以下読んでみてくださいー。
使用データ
$ cat input/access.log-20131212 www.hoge.com 1.1.1.1 - - "POST /user/aaaaa HTTP/1.1" 200 61 ... www.hoge.com 1.1.1.1 - - "POST /user/bbbbb HTTP/1.1" 200 61 ... www.hoge.com 1.1.1.1 - - "GET /hoge HTTP/1.1" 200 9570 ... www.hoge.com 1.1.1.1 - - "POST /user/ccccc HTTP/1.1" 200 61 ... www.hoge.com 1.1.1.1 - - "GET /photo HTTP/1.1" 302 5 ... www.hoge.com 1.1.1.1 - - "POST /user/ddddd HTTP/1.1" 200 61 ... www.hoge.com 1.1.1.1 - - "POST /user/eeeee HTTP/1.1" 200 61 ... www.hoge.com 1.1.1.1 - - "GET /bar HTTP/1.1" 200 779 ... www.hoge.com 1.1.1.1 - - "POST /foo HTTP/1.1" 200 313 ... www.hoge.com 1.1.1.1 - - "GET / HTTP/1.1" 200 20912 ... www.hoge.com 1.1.1.1 - - "GET /hoge HTTP/1.1" 302 5 ... www.hoge.com 1.1.1.1 - - "GET /video/100 HTTP/1.1" 200 74 ... www.hoge.com 1.1.1.1 - - "GET /video/100 HTTP/1.1" 200 74 ... $ cat input/access.log-20131213 www.hoge.com 1.1.1.1 - - "POST /user/AAAAA HTTP/1.1" 200 61 ... www.hoge.com 1.1.1.1 - - "POST /user/BBBBB HTTP/1.1" 200 61 ... www.hoge.com 1.1.1.1 - - "GET /hoge HTTP/1.1" 200 9570 ... www.hoge.com 1.1.1.1 - - "POST /user/CCCCC HTTP/1.1" 200 61 ... www.hoge.com 1.1.1.1 - - "GET /photo HTTP/1.1" 302 5 ... www.hoge.com 1.1.1.1 - - "POST /user/DDDDD HTTP/1.1" 200 61 ... www.hoge.com 1.1.1.1 - - "POST /user/EEEEE HTTP/1.1" 200 61 ... www.hoge.com 1.1.1.1 - - "GET /bar HTTP/1.1" 200 779 ... www.hoge.com 1.1.1.1 - - "POST /foo HTTP/1.1" 200 313 ... www.hoge.com 1.1.1.1 - - "GET / HTTP/1.1" 200 20912 ... www.hoge.com 1.1.1.1 - - "GET /hoge HTTP/1.1" 302 5 ... www.hoge.com 1.1.1.1 - - "GET /video/100 HTTP/1.1" 200 74 ... www.hoge.com 1.1.1.1 - - "GET /video/100 HTTP/1.1" 200 74 ...
スクリプト
POSTを使っているユーザ=POST /user/<ここ>を抜き出す。
$ cat analysis_log.sh #!/usr/bin/bash for current_file in `ls input` do cnt=1 # read関数を使いパイプで受け取ったものを$lineに格納。 # http://d.hatena.ne.jp/r_ikeda/20110503/read cat input/${current_file} | while read line do # 現在どこを処理しているか表示。 echo File: $current_file Line: $cnt if expr "$line" : ".*POST /user/[a-zA-Z].*" > /dev/null; then # ×$1 ○1 echo $line | sed -e "s/.*POST \/user\/\([a-zA-Z]*\).*/\1/g" >> output/$current_file fi # shell scriptは変数の値を文字列として扱う。 # 数字の演算だと示すためletを使用。 # let cnt = $cnt + 1とスペースを空けて書くとcntも関数だと思われてしまう。 # http://ameblo.jp/oyasai10/entry-10895223731.html # http://d.hatena.ne.jp/JOlantern/20111202/1322821849 let cnt=$cnt+1 done done
実行結果
$ sh analysis_log.sh File: access.log-20131212 Line: 1 File: access.log-20131212 Line: 2 File: access.log-20131212 Line: 3 File: access.log-20131212 Line: 4 File: access.log-20131212 Line: 5 File: access.log-20131212 Line: 6 File: access.log-20131212 Line: 7 File: access.log-20131212 Line: 8 File: access.log-20131212 Line: 9 File: access.log-20131212 Line: 10 File: access.log-20131212 Line: 11 File: access.log-20131212 Line: 12 File: access.log-20131212 Line: 13 File: access.log-20131213 Line: 1 File: access.log-20131213 Line: 2 File: access.log-20131213 Line: 3 File: access.log-20131213 Line: 4 File: access.log-20131213 Line: 5 File: access.log-20131213 Line: 6 File: access.log-20131213 Line: 7 File: access.log-20131213 Line: 8 File: access.log-20131213 Line: 9 File: access.log-20131213 Line: 10 File: access.log-20131213 Line: 11 File: access.log-20131213 Line: 12 File: access.log-20131213 Line: 13 $ cat output/access.log-2013121* | head aaaaa bbbbb ccccc ddddd eeeee AAAAA BBBBB CCCCC DDDDD EEEEE