grepコマンド
grepは一定の条件に適った行を探すコマンドです。
基本構文は下記の通りですが、
grep ‘検索文字’ 検索したいファイル
検索文字の設定の際に、検索を容易にする為に特殊な文字(メタ文字)が使用できます。
今回は、主にそのメタ文字の話。
正規表現
正規表現 ( BRE : Basic Regular Expressions ) とは、そのメタ文字の使用方法に関する規則です。
この正規表現は、grepコマンド以外にも、 ” sed ” , ” awk ” , ” find ” , ” less ” など多くのコマンドで使用できます。
但し、ややこしいことにコマンドによって少しずつ規則が違います。
ここではgrepを基準にして話を進めます。
拡張正規表現
さらにややこしいことに正規表現を拡張した、拡張正規表現 ( ERE : Extensive Regular Expression ) があります。
grepの場合、 ” -E ” オプション(grep -E)若しくは ” egrep ” コマンドでEREが使用できます。
” grep -E ” と ” egrep ” は同等です。
これにより使用できるメタ文字の種類が増えます。
バックスラッシュ ‘\’
さらにさらに、話をややこしくするのがバックスラッシュ ‘\’ の存在です。
ちなみにmacでは ‘\’ の文字は、 ” option + ¥ ” で出せます。
windowsのキーボードでは右下の ‘ろ’ のキー位置にあります。
バックスラッシュ ‘\’ は直後にある文字の打ち消しの意味で使用します。
- 例えばドット ‘.’ はそのまま使用すれば、「任意の1文字」という意味を割り当てられた特殊記号(メタ文字)です。
- しかし場合によってはドットという文字を本来の文字として検索語句の中に含めたい場合があります。
- その場合、打ち消しの意味の ‘\’ を前に置いて、 ‘\.’ とすれば、 ‘.’ という普通の文字として扱われます。
上の例では ‘\’ が(メタ文字 → 普通文字)変換の意味で使われましたが、
ややこしいのは、逆方向の(普通文字 → メタ文字)変換の意味でも ” \ ” が使われます。
具体的には、
- BREではメタ文字扱いではないけれど、EREではメタ文字に指定されている文字において、
- その文字をgrepで検索する時には、 ‘\’ を付けます(つまり普通文字 → メタ文字変換に使用)
- 但し同じ文字をegrepで検索する時は普通にそのままメタ文字として使用出来ます
- そしてその文字をegrepで普通文字として使う時は ‘\’ を付ける(メタ文字 → 普通文字変換)
ここまで来るとややこしさの極みと言えますが、表にまとめると下記の通りです。多分ね
使用する文字の種類 | 具体例 | 文字の意味 | 使用コマンド | メタ文字として使用 | 普通文字として使用 |
---|---|---|---|---|---|
BREでメタ文字として扱われる文字 | . * ^ $ [ ] | 任意の1文字 直前の文字0回以上 行頭 行末 文字クラス | grep, egrep, grep -E | x | \x |
EREでメタ文字として扱われる文字 | ? + | ( ) { } | 0又は1回 1回以上 又は グループ化 繰り返し | grep | \x | x |
同上 | 同上 | 同上 | egrep, grep -E | x | \x |
BREの ‘|’ (又は)は、EREでは ‘`’ (@をshiftして出てくる文字)でもOKです。
これだけでは中々イメージが湧かないので以下に具体例を示します。
具体例
基本パターン
grep ‘^abc’ file.txt
行頭が ‘abc’ で始まる行を検索
grep ‘abc$’ file.txt
行末が ‘abc’ で終わる行を検索
グループ化:()を使用
‘abc’ 又は ‘def’ のどちらかの文字列を含む行を検索したい
# BREの場合(\必要)
grep ‘\(abc\|def\)’ file.txt
再掲:‘\(abc\|def\)‘:'(‘ と ‘|’ と ‘)’ の3文字がメタ文字として扱われます。
# EREの場合(grep -E 又はegrepなら\不要)
grep -E ‘(abc|def)’ file.txt
文字クラス:[]を使用
指定した文字のどれか1文字にマッチ。
a, b, cのいずれかで始まる行を検索
grep ‘^[abc]’ file.txt
小文字アルファベットで始まる行
grep ‘^[a-z]’ file.txt
‘[‘ の前に先頭の意味で ‘^’ のメタ文字が使われています。
小文字以外で始まる行(否定クラス)
grep ‘^[^a-z]’ file.txt
aの前の ‘^’ は否定の意味で使われているメタ文字です。必ず ‘[ ]’ 内にあります。(先頭の意味の ‘^’ とは別)
ちなみに大文字小文字の区別をしないオプションは ” grep -i ”
繰り返し
0回以上: *
‘ab’ の後に ‘c’ が0回以上続く行を検索
grep ‘abc*’ file.txt
‘ab’, ‘abc’, ‘abcc’, ‘abccc’ などを含む行が検索される。(0回でも良い)
1回以上: +
‘c’ が1回以上続いている行を検索
# BRE(\+ 必要)
grep ‘c\+’ file.txt
再掲:‘c\+‘:’+’ がメタ文字として扱われます。
# ERE
grep -E ‘c+’ file.txt
0回または1回: ?
# BRE
grep ‘colou\?r’ file.txt
再掲:‘clou\?r’:’?’ がメタ文字として扱われます。
# ERE
grep -E ‘colou?r’ file.txt
“color” または “colour” にマッチします。
回数指定: {n}, {n,}, {n,m}
# aがちょうど3回
# BRE
grep ‘a\{3\}’ file.txt
再掲:‘a\[3\]‘:'[‘ と’]’ がメタ文字として扱われます。
# ERE
grep -E ‘a{3}’ file.txt
# aが3回以上
このくらいになるとEREの方が便利になります。
grep -E ‘a{3,}’ file.txt
# aが2〜4回
grep -E ‘a{2,4}’ file.txt
正規表現はまだ奥が深いです(BRE, EREの先にはPCREがあります)が、今回はこの辺で。
まとめ
grepの正規表現は暗号というか呪文というか、非常に難解なものがあります。
カッコが何重にも重なった構文など、名前・生年月日・電話番号などのテキストを整形する目的などに多用されてます。
自分であまり複雑なものを使用することはないと思いますが、解読する場面はあり得ると思います。
コメント