##はじめに
ひよっこエンジニアです。初心者向けにgrepを用いた正規表現検索についてまとめています。また、様々なパターンを調べるために、簡単な問題と解説を用意したのでトライしてみてください。
##正規表現
記号や文字列を組み合わせて、目的のキーワードを見つけるためのパターンを作り、検出する方法。
記号はメタキャラクタ
と呼ばれ、記号にそれぞれ意味がある。
##主なメタキャラクタ
記号 | 意味 | 備考 |
---|---|---|
^ | 先頭 | |
$ | 末尾 | |
|直後の一文字をエスケープ | ||
. | 任意の一文字 | |
* | 直前の文字が0回以上繰り返し | |
? | 直前の文字が0回か1回繰り返し | 拡張正規表現 |
+ | 直前の文字が1回以上繰り返し | 拡張正規表現 |
{ } | 直前の文字を{}の回数繰り返し | 拡張正規表現 |
[ ] | [ ]で囲まれた文字のうち一文字に一致 |
?
や+
は拡張正規表現と呼ばれ、
-
egrep
コマンド -
grep
に-E
オプション をつけた場合
に使用することができる。
##[ ]による文字グループ
例 | 意味 |
---|---|
[abc] | a,b,cのいずれかの文字 |
[a-c] | a,b,cのいずれかの文字(上と同じ) |
[a-cA-C] | a,b,c,A,B,Cのいずれかの文字 |
[^abc] | a,b,c以外の文字 |
#例題
以降、grepコマンドを用いて文字列を検索する例題を記述していく。
※grepコマンドの使い方
$grep {検索したい文字列} {検索したいファイル名}
$ grep UNIX01 file1
UNIX01
##SECTION1
SECTION1は下記の例題とfile1でやっていきます。
【例題】
例1: $ grep '^U' file1
例2: $ grep '[xX]' file1
例3: $ grep '^U.*1$' file1
例4: $ grep '.' file1
例5: $ grep '\.' file1
例6: $ grep '^[^0-9]' fileA
$ cat file1
UNIX01
UNIX02
Linux01
Linux10
.
RedHat10
RedHat11
###例1
先頭がUで始まるの検索。
$ grep '^U' file1
UNIX01
UNIX02
###例2
x,Xが含まれている行の検索。
$ grep '[xX]' file1
UNIX01
UNIX02
Linux01
Linux10
###例3
先頭がUで始まり、任意の文字を0回以上繰り返して、最後は1で終わる行の検索。
$ grep '^U.*1$' file1
UNIX01
###例4
任意の一文字が含まれる行の検索。(= 空白行以外の全てを検索)
$ grep '.' file1
UNIX01
UNIX02
Linux01
Linux10
.
RedHat10
RedHat11
###例5
ピリオドを含む行の検索。
\
の後の文字はエスケープされるため.
はメタキャラクタではなく文字としてとらえる。
$ grep '\.' file1
.
###例6
先頭が数値以外の行を検索。
$grep '^[^0-9]' fileA
UNIX01
UNIX02
Linux01
Linux10
.
RedHat10
RedHat11
##SECTION2
SECTION2は下記の例題とfile2でやっていきます。
【例題】
例7: $ grep '[0-9][0-9]*' file2
例8: $ grep '[0-9]*' file2
例9: $ grep '1.bak' file2
例10: $ grep '1.' file2
例11: $ grep '^centOS[^0-9][^A-C].*k$' file2
例12: $ grep '^centOS0[^1-9]*.bak' file2
例13: $ grep -E '^centOS10?' file2
例14: $ grep -E '10|AA' file2
例15: $ grep -E '^centOS[^1-9]{5}.bak' file2
$ cat file2
centOS01.bak
centOS10.bak
centOS123.bak
centOS00000.bak
centOSAAA.bak
centOSABC.bak
centOS.bak
###例7
一桁の数値を含むor二桁以上の数値を含む行の検索。
$ grep '[0-9][0-9]*' file2
centOS01.bak
centOS10.bak
centOS123.bak
centOS00000.bak
###例8
0桁の数値を含むor一桁以上の数値を含む行の検索。
$ grep '[0-9]*' file2
centOS01.bak
centOS10.bak
centOS123.bak
centOS00000.bak
centOSAAA.bak
centOSABC.bak
centOS.bak
例⑦と比較すると分かるように、「0桁の数値を含む」≒ 全て
を含むことになり全行検索される。
###例9
1.bak
が含まれる行の検索。
$ grep '1.bak' file2
centOS01.bak
###例10
1の後に任意の文字が含まれる行の検索。
$ grep '1.' file2
centOS01.bak
centOS10.bak
centOS123.bak
###例11
先頭がcentOS
から始まり、次に数値以外の文字、次にA,B,C以外の文字を0回以上繰り返して、kで終わる行の検索。
$ grep '^centOS[^0-9][^A-C].*k$' file2
centOS.bak
###例12
先頭がcentOS0
から始まり、次に1〜9以外の文字を0回以上繰り返して、.bakで終わる行の検索。
$ grep '^centOS0[^1-9]*.bak' file2
centOS00000.bak
###例13
先頭がcentOS1
から始まり、0が0回以上、もしくは1回の繰り返しに一致する検索。
$ grep -E '^centOS10?' file2
centOS10.bak
centOS123.bak
?
は拡張正規表現で使用されるメタキャラクタで、直前の文字が0回以上もしくは1回の繰り返しに一致
する。
centOS123.bak
は?の直前の文字(=0)が0回の繰り返しの時に該当し、
centOS10.bak
は?の直前の文字(=0)が1回の繰り返しの時に該当する。
-Eオプションは拡張正規表現を使用する際に付けなければならない。
また下記のようにegrepコマンドを使用することもできる。
$ egrep 'centOS10?' file2
centOS10.bak
centOS123.bak
###例14
10
もしくはAA
を含む行を検索。
$ grep -E '10|AA' file2
centOS10.bak
centOSAAA.bak
|
を挟む左右のどちらかに一致する行を検索する。
これも拡張正規表現のため-Eオプションまたはegrepコマンドを使用する必要がある。
ちなみに、|
を複数使用することも可能。
$ grep -E '10|AA|AB' file2
centOS10.bak
centOSAAA.bak
centOSABC.bak
###例15
先頭がcentOS
から始まって、1~9
以外の文字を5回繰り返して、.bak
で終わる行を検索。
$ grep -E '^centOS[^1-9]{5}.bak' file2
centOS00000.bak
{}
が拡張正規表現のため-Eオプションまたはegrepコマンドを使用する必要がある。
##SECTION3
SECTION3は下記の例題と
序盤で作成したfile1をもう一度使ってやっていきます。
【例題】
例16: $ grep -i '[Ix]' file1
例17: $ grep -v '0.' file1
例18: $ grep -F '.' file1
$ cat file1
UNIX01
UNIX02
Linux01
Linux10
.
RedHat10
RedHat11
###例16
i,I,x,Xが含まれる行を検索。
$ grep -i '[Ix]' file1
UNIX01
UNIX02
Linux01
Linux10
-iオプションは小文字大文字の区別をしない。
###例17
0の後に任意の一文字が含まれる行以外を検索。
$ grep -v '0.' file1
Linux10
RedHat10
RedHat11
0の後に任意の一文字が含まれる行以外を検索する。
-vは指定されたパターン以外の行を検索するオプション。
下記のーvを付けなかった場合と比較すると理解しやすいかもしれない。
$ grep '0.' file1
UNIX01
UNIX02
Linux01
###例18
.
を含む行を検索する。
$ grep -F '.' file1
.
-Fオプションは指定された文字列をそのまま検索するため、.
をメタキャラクタとして扱わない。
-Fオプションを付けない場合、メタキャラクタとして扱われ
任意の一文字を含む行を検索するため下記のようになる。
$ grep '.' file1
UNIX01
UNIX02
Linux01
Linux10
.
RedHat10
RedHat11
ちなみに$fgrep '.' file1
でも同じ挙動になる。
##終わりに
何か間違いがありましたらご指摘いただけると幸いです。