はじめに
どうも、未経験からエンジニア転職を目指しているもきおです。
今回はLinuxの grepと正規表現 に触れていきたいと思います。
どちらも重要で共にLinux以外でも様々なプログラミング言語でも使われるので覚えておいて損はないと思いました。
今回の記事は新しいLinuxの教科書を参考にしています。
とてもLinux標準の教科書もやった事はありますが、よりわかりやすくまとまっているのでLinuxを学びたい方におすすめです!
grepコマンド
grepコマンドは文字列を検索するコマンドです。
Ruby on Railsにおいてrails routes | grep [絞り込みたい文字列]みたいに使用した方もいるのではないでしょうか?
grepを使用する際の書式は以下となります。
書式:
grep 【オプション】<検索パターン> <ファイル名>
オプションには以下のようなものがあります。
オプション | 意味 |
---|---|
-n | 行番号付きで表示する |
-i | 大文字小文字の区別なく検索する |
-v | 指定した検索パターンを含まない行を検索する |
使用例
# /etc/passwdファイルからbashという文字列を含む行を表示
$ grep bash /etc/passwd
root:x:0:0:root:/root:/bin/bash
# /etc/passwdファイルから-nを使用しbashという文字列を含む行を行番号付きで表示
$ grep -n bash /etc/passwd
12: root:x:0:0:root:/root:/bin/bash
# /etc/passwdファイルから-iを使用し大文字、小文字区別せずsystemという文字列を含む行を表示
$ grep -i system /etc/passwd
dbus:x:81:81:System message bus:/:/sbin/nologin
正規表現
そもそも正規表現ってなに?
プログラミングをやっていると時々耳にするこの「正規表現」、自分は最初たまに耳にするけど正規表現が何かよくわかってませんでした。
普段私たちが検索したいものは固定文字列ばかりではないと思います。例えば「Beer」という文字列だけでなく「Beeeer」という文字列も含めて検索したいとしましょう。「Beer」と検索しても「Beeeer」を検索一致させることは出来ません。
このような検索を行う際に、条件文字列の集合を表現するための記法が正規表現です。
正規表現を使用する際の注意点
正規表現を使用する際は「' '」(シングルクォーテーション)でくくっておかないとシェルに正規表現が展開され自分の意図しない実行をされてしまう可能性があります。
例えば「ab*」で「ab」や「abbb」等を含めて検索したいとしましょう。
「' '」(シングルクォーテーション)でくくっておかないと以下のように解釈されてしまいます。
$ grep ab* sample.txt
## シェルが展開され実際に実行されてしまうコマンド
$ grep ab.txt ab.sh sample.txt
よって正規表現を使用する際はシングルクォーテーションでくくっておいて損はないでしょう。
正規表現実用例
ここからは実際にgrepと正規表現を使用した例を紹介していきます。
メタ文字って何?
正規表現では**「* {} $」**等の記号が特別な意味を持ちます。正規表現で意味を持つこのような記号をメタ文字と言います。
文字にマッチするメタ文字
まず最初に任意の文字にマッチするメタ文字の正規表現を紹介します。
メタ文字 | 意味 |
---|---|
. | 任意の1文字 |
[ ] | []の中に含まれる、いずれかの1文字 |
[^ ] | []の中に含まれない、いずれかの1文字 |
|直後のメタ文字の意味を打ち消す |
よく使いそうな使用例一覧
今回使用するファイルは以下
test.example.net
tfst.example.net
tzst.example.net
tzzst.example.net
www.example.com
www.example.org
netapp.example.com
mail1.example.com
mail3.example.com
mail7.example.com
borg.example.com
$ grep 't.st' example.txt
test.example.net
tfst.example.net
tzst.example.net
t.stで「tの後ろに任意の1文字が続き、その後ろにstという文字列がくる」というパターン検索をすることができます。
$ grep 't..st' example.txt
tzzst.example.net
「..」と二つ続けると任意の2文字を指定することができます。
$ grep '\.org' example.txt
www.example.org
.(ドット)そのものを検索したい場合は直前に\を置いて記載することでメタ文字の意味を打ち消すことができます。このように特別な意味を持つ文字の意味を打ち消すことを「エスケープする」と言います。
$ grep 't[ef]st' example.txt
test.example.net
tfst.example.net
t[ef]stとするとtest、tfstの両方にマッチする検索ができます。
ここでよく使用されそうなのが[a-z A-Z]による全てのアルファベット大小関係なく検索する方法や[1-4]のように1,2,3,4が含まれる全ての文字列を検索する表記法です。
# 大小関係なく全てのアルファベットに一致するものを検索
$ grep 't[a-z A-Z]st' example.txt
test.example.net
tfst.example.net
tzst.example.net
# 1-4の数字のみマッチするものを検索
$ grep 'mail[1-4]' example.txt
mail1.example.com
mail3.example.com
位置にマッチするメタ文字
次に、位置にマッチするメタ文字の正規表現を紹介します。
メタ文字 | 意味 |
---|---|
^ | 行頭を意味するメタ文字 |
$ | 行末を意味するメタ文字 |
実際の使用例
行頭がnetという文字列で始まる行を検索したいとしましょう。
単純にnetというパターンで検索すると以下のようになってしまいます。
$ grep 'net' example.txt
test.example.net
tfst.example.net
tzst.example.net
tzzst.example.net
netapp.example.com
これだと行頭以外でもnetの文字列が含まれる行が検索されてしまいました。そこで行頭を意味する^を使用すると行頭でnetという文字列がある行だけ検索することができます。また行末の文字列を検索したい場合は文字列の末尾に$を使用することで可能です。
# 行頭のみマッチするものを検索
$ grep '^net' example.txt
netapp.example.com
# 行末のみマッチするものを検索
$ grep 'net$' example.txt
test.example.net
tfst.example.net
tzst.example.net
繰り返しを指定するメタ文字
最後に繰り返しを表すメタ文字の正規表現を紹介します。
メタ文字 | 意味 |
---|---|
* | 0回以上の繰り返し |
\{m,n\} | m回以上n回以下の繰り返し |
\{m\} | ちょうどm回の繰り返し |
\{m,\} | m回以上の繰り返し |
※全角のバックスラッシュじゃないとうまく表が作れなかったので全角にしていますが本来は半角のバックスラッシュです。 |
よく使いそうな使用例一覧
今回使用する元ファイルは以下
Ber
Beer
BeerBeer
BeerBeerBeer
Beeeeeeer!!!
Bear
My Vodka
My Wine
Wine Wine
WineWine
メタ文字*による繰り返し
*を使用する事によって0回以上の繰り返しを表すことができます。
ここでの0回とは、その直前の文字が存在しなくても検索条件に一致するということです。
$ grep 'Be*r' drink.txt
Ber
Beer
BeerBeer
BeerBeerBeer
Beeeeeeer!!!
Br
よって「Ber」、「Beeeeeer」だけでなく「Br」もマッチします。一方「Bear」にはマッチしません。
「Bear」を*を使用し繰り返しによってマッチさせるには先程使用した[ ]を使用しB[ae]*rと記載することで検索することが可能です。
$ grep 'B[ae]*r' drink.txt
Ber
Beer
BeerBeer
BeerBeerBeer
Beeeeeeer!!!
Bear
Br
あとがき
いかがだったでしょうか?
今回は今回はgrepと正規表現に触れました。
正規表現による組み合せの可能性は無限大で、Linux上級者の中では奇抜な正規表現を考えることを競い合ったりもしているらしいです。
ここら辺は今後かなり使えそうな分野なのでしっかりと理解を深めていきたいと思います!
最後までご覧いただきありがとうございました!!
参考記事
[【sed / awk / grep】文字列の置換・抽出・検索と正規表現 | Linux Cheat Sheet]
(https://qiita.com/shuntaro_tamura/items/e4e942e7186934fae5e7)