正規表現

May 14, 2018

正規表現

正規表現は、特定の条件を表す文字列を抽象的に表現したもの。
よく使われるのは以下。

記号 説明
. 任意の一文字
* 直前の文字の 0 回以上の繰り返し
[] [] 内のいずれか 1 文字。 -: 範囲を指定 ^: 先頭にあるときは ~ 以外 を表す
^ 行頭
$ 行末
\ 次にくる文字をメタキャラではなく通常の文字として処理する

grep コマンド

grep コマンドは、ファイルやテキストストリームの中に正規表現によって表される検索文字列があるかどうか調べ、マッチする文字列が含まれる行を表示する。

オプション 説明
-c パターンがマッチした行の行数だけを表示
-f 検索パターンをファイルから読み込む
-i 大文字小文字を区別しない
-n 検索文字列と合わせて行番号も表示
-v パターンにマッチしない行を表示
-E 拡張正規表現を使用
$ cut -d " " -f 9 < alb_access_log.log | grep 200 | wc -l  
27  
  
```bash  
$ grep -v '^https' alb_access_log.log | head -10 | cut -d " " -f 1,2,4,5  
http 2018-05-14T03:52:14.205764Z 126.199.87.122:26609 10.1.11.207:32786  
http 2018-05-14T03:52:15.483412Z 126.199.87.122:26609 10.1.11.207:32785  
http 2018-05-14T03:52:16.755637Z 126.199.87.122:26609 10.1.11.207:32783  
http 2018-05-14T03:52:17.898212Z 126.199.87.122:26609 10.1.11.207:32786  
http 2018-05-14T03:52:19.058210Z 126.199.87.122:26609 10.1.11.207:32785  
http 2018-05-14T03:52:19.777192Z 126.199.87.122:26609 10.1.11.207:32783  
http 2018-05-14T03:52:21.028178Z 126.199.87.122:26609 10.1.11.207:32786  
http 2018-05-14T03:52:21.858266Z 126.199.87.122:26609 10.1.11.207:32785  
http 2018-05-14T03:52:22.187259Z 126.199.87.122:26609 10.1.11.207:32783  
http 2018-05-14T03:52:22.558308Z 126.199.87.122:26609 10.1.11.207:32786  

拡張正規表現を使うには -E オプションを用いるか egrep コマンドを用いる。
拡張正規表現の例は以下。

メタキャラクタ 説明
+ 直前の文字の 1 回以上の繰り返し
? 直前の文字の 0 回もしくは 1 回の繰り返し
$ egrep https? alb_access_log.log | head -10 | cut -d " " -f 1,2,4,5  
https 2018-05-14T03:52:13.111733Z 223.71.238.24:62539 -  
http 2018-05-14T03:52:14.205764Z 126.199.87.122:26609 10.1.11.207:32786  
http 2018-05-14T03:52:15.483412Z 126.199.87.122:26609 10.1.11.207:32785  
https 2018-05-14T03:52:15.686589Z 223.71.238.24:62542 -  
http 2018-05-14T03:52:16.755637Z 126.199.87.122:26609 10.1.11.207:32783  
https 2018-05-14T03:52:17.298601Z 223.71.238.24:62543 -  
https 2018-05-14T03:52:17.620916Z 125.92.89.186:13581 -  
http 2018-05-14T03:52:17.898212Z 126.199.87.122:26609 10.1.11.207:32786  
http 2018-05-14T03:52:19.058210Z 126.199.87.122:26609 10.1.11.207:32785  
http 2018-05-14T03:52:19.777192Z 126.199.87.122:26609 10.1.11.207:32783  
$ egrep '(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])' alb_access_log.log | tail -5  
https 2018-05-14T03:54:55.293111Z app/LogChance-Frontend/5b4d7e7b8487ead6 223.71.238.24:62727 - -1 -1 -1 400 - 0 288 "- http://logchance-frontend-1423232053.ap-northeast-1.elb.amazonaws.com:443- -" "-" - - - "-" "-" "-" - 2018-05-14T03:54:55.190000Z "-"  
https 2018-05-14T03:54:56.185081Z app/LogChance-Frontend/5b4d7e7b8487ead6 223.71.238.24:62730 - -1 -1 -1 400 - 0 288 "- http://logchance-frontend-1423232053.ap-northeast-1.elb.amazonaws.com:443- -" "-" - - - "-" "-" "-" - 2018-05-14T03:54:56.079000Z "-"  
https 2018-05-14T03:54:58.638277Z app/LogChance-Frontend/5b4d7e7b8487ead6 223.71.238.24:62731 - -1 -1 -1 400 - 0 288 "- http://logchance-frontend-1423232053.ap-northeast-1.elb.amazonaws.com:443- -" "-" - - - "-" "-" "-" - 2018-05-14T03:54:58.532000Z "-"  
https 2018-05-14T03:55:00.544947Z app/LogChance-Frontend/5b4d7e7b8487ead6 223.71.238.24:62735 - -1 -1 -1 400 - 0 288 "- http://logchance-frontend-1423232053.ap-northeast-1.elb.amazonaws.com:443- -" "-" - - - "-" "-" "-" - 2018-05-14T03:55:00.439000Z "-"  
https 2018-05-14T03:55:00.578466Z app/LogChance-Frontend/5b4d7e7b8487ead6 218.244.55.118:53011 - -1 -1 -1 400 - 0 288 "- http://logchance-frontend-1423232053.ap-northeast-1.elb.amazonaws.com:443- -" "-" - - - "-" "-" "-" - 2018-05-14T03:55:00.520000Z "-"  

検索パターンに正規表現を使わない場合は fgrep を使う。

$ fgrep '.*' alb_access_log.log   

sed コマンド

sed はテキストストリームに対して編集を行う。
sed では、編集する内容をコマンドやスクリプトとして sed に指示しておき、sed はその指示に基づいてストリームの編集を行い、標準出力に結果を書き出す。

d コマンド

ファイルの 1 ~ 5 行目を削除する。

$ sed '1,5d' alb_access_log.log > deleted_access_log.log  
$ diff alb_access_log.log deleted_access_log.log | sed '1d' | wc -l  
5  

s コマンド

ファイルの特定の文字列を置換する。

$ cat alb_access_log.log | cut -d " " -f 3 | head -1  
app/LogChance-Frontend/5b4d7e7b8487ead6  
$ sed s/LogChance/hogehoge/g alb_access_log.log | cut -d " " -f 3 | head -1  
app/hogehoge-Frontend/5b4d7e7b8487ead6  

1 ~ 5 行目のみ、行頭に HELLO を追加。

$ sed '1,5s/^/HELLO/g' alb_access_log.log | head -10 | cut -d " " -f 1  
HELLOhttps  
HELLOhttp  
HELLOhttp  
HELLOhttps  
HELLOhttp  
https  
https  
http  
http  
http  

y コマンド

「y/検索文字/置換文字」という形で使うと、ストリーム中にマッチする文字列があった場合に、その文字を置換文字の同じ位置の文字に置き換える。

$ sed y/htp/god/ alb_access_log.log | head -5 | cut -d " " -f 1  
goods  
good  
good  
goods  
good  

awk コマンド

参考: awkコマンドの基本

awk は列に対する処理が得意なコマンド。
“print $1” のような形で各フィールドを取り出す。
例えば以下のような、StatusCode=200 の時の全体のエントリを加工したい時など。

$ awk '($9 == 200) {print $0}' alb_access_log.log | cut -d " " -f 2,4,5 | head -5  
2018-05-14T03:52:14.205764Z 126.199.87.122:26609 10.1.11.207:32786  
2018-05-14T03:52:15.483412Z 126.199.87.122:26609 10.1.11.207:32785  
2018-05-14T03:52:16.755637Z 126.199.87.122:26609 10.1.11.207:32783  
2018-05-14T03:52:17.898212Z 126.199.87.122:26609 10.1.11.207:32786  
2018-05-14T03:52:19.058210Z 126.199.87.122:26609 10.1.11.207:32785  

 © 2023, Dealing with Ambiguity