🖥️

Envaderを利用して、正規表現について学ぶ

2022/03/27に公開

今回は、Envaderを利用して、私自身非常に苦手意識の強い正規表現について学んだので、そのまとめと振り返りです。

今回も学習環境としては、Linuxにおける環境構築が不要で、Linuxを体験できるオンライン学習サービスEnvaderを利用しました。

Envaderとはなんぞや?という方がいらっしゃいましたら、リンクを貼っておきますので参考にどうぞ。

Envaderコース一覧

今回使用したシナリオ

正規表現(Regular Expression)

正規表現は、シェルのメタキャラクタと同じで、任意の文字列パターンを表すための表記方法。
正規表現を利用することで、ファイル内の文字列を柔軟に検索することが可能になる。

シェルのメタキャラクタに関する記事はこちらがわかりやすかったです。
Linuxのメタキャラクタ~メタキャラクタについて~

メタキャラクタと正規表現は同じものだと思ってました。

と、思って違いを検索していたのですが、何やら深い所で表現の仕方が難しいみたいです。

正規表現とワイルドカードは違います

だから、正規表現とワイルドカードは違うんだって

波乱を呼びそうですが、正式な意味合いについては詳しい方々にお任せします。

grepコマンド

正規表現と一緒に紹介されている頻度が高いのがgrepコマンドなのかなと感じています。
出来る事として、ファイルやディレクトリ、ファイルの中身を絞り込んで検索することができるコマンドです。

使い方の基本

grep 検索したい文字 ファイル名

基本はこの使い方で良さそうです。

Envaderにて試して見ます。

# secrets.txtの中身abの文字を検索

envader@172-19-2-2:~$ grep ab secrets.txt

sacret=a4d0bfed76865f9a75abafdc5aef6f66
sacret=8e109e82a6f9fabdb6d5489608e12dfb
sacret=e41be0cb6b646e9a44c97153ab8ddb07
secret=4c8136aba4ba90eceb3206fb8dc53be0
sacret=59c9ab0073053950ad1e9326b019c540
sacret=1e96a6f5c8c9abd38021ff69caacc9a6
sacret=49d255840da28924cad6cc4abc4c3294
sacret=127ebbabb48274c8a4e3689c7b53eec9
sacret=1120916b99d24bb3d847e2cc568ab5ec
sacret=65b7f9034251ed87a13ba1b52abc6c12
sacret=be665ba933eadbddbb3ab5efc31807c4
sacret=c11bc63b936d005873b08c77974ab0cd
sacret=552b0f34c0b392999c43c9eab7b1add2

確かにabの文字を含むテキストを検索できました。
これで対象をabに絞り込んで検索できています。

ただ、正規表現を利用することによって、これよりもさらに詳細に条件を指定して検索をすることができます。

正規表現の種類

特殊文字 意味
. 任意の一文字がある(文字はなんでも良くて、ドットの数だけ文字がある)
* 直前の文字を0回以上繰り返す。
[] []の中に入っている文字のどれか1文字があることを意味する。
[^文字] []の中に入っている以外の文字を表す
^ 行頭の文字
$ 行末の文字
\ 次に来る文字を特殊文字ではなく通常の文字として処理をする

まだまだ検索すると出てきそうですが、この記事ではこのくらいに留めておきます。

結構これを理解して使いこなすには慣れが必要そうですね。
なぜか私はこの考え方がなかなか理解できずに、勝手に苦手意識がありました。

正規表現を使ってみる。

上記の正規表現について、実際に使って見て理解したいと思います。

.を使って任意の一文字を検索

# secrets.txtの中から、aからcまでの間の2文字はなんでもいいから検索

envader@172-19-2-2:~$ grep a..c secrets.txt

sacret=a4d0bfed76865f9a75abafdc5aef6f66
sacret=b3fe0800f16db550a7bcd19d7a79ae08
sacret=2533c3b035d29216faeec65275bb04ba
sacret=35aed67b1626bb7dbec413f5a20c5c9f
sacret=664cfc313ecad901f28090a09c0c4de7
sacret=e41be0cb6b646e9a44c97153ab8ddb07
sacret=1e96a6f5c8c9abd38021ff69caacc9a6
sacret=49d255840da28924cad6cc4abc4c3294
sacret=fb1aedda6c2d169ef9d12a38cfb47331
sacret=4528a29d1da9fc40b1103339a65e0984
sacret=3bfea13c0c2fc9c8e106313ac1cf8aa3
sacret=c6c3ba38e00a3ec2304596733fa26a00
sacret=fe9a5cc8ef0bf10faf52f7a5e136ebe1
sacret=c11bc63b936d005873b08c77974ab0cd

これ、本当かと思って確認しましたが、本当にa..cでファイルの中身が検索できていました。
すごい。

[]を使って[]内のいずれか一文字を含むものを検索

# secrets.txtの中に、bで始まって1か2の後にcがくる文字列を検索 b12cではない

envader@172-19-2-2:~$ grep b[12]c  secrets.txt

sacret=37b5f9aec439ee77c7ad4b1c8ada856c
sacret=d8b1c0f550e4742e3f6178f86fb14b54
sacret=6c592c2d8392ca9f4612fb2c72e84417
sacret=3c1b2c017f60968f1a8a9611345b57fd

これもちゃんと検索できていますね。
混同してしまいそうなのが、b12cは検索対象ではなくて、b1cb2cがあくまで検索対象になるって事でした。

^$を使って、行頭と行末を検索

# ^を使って行頭の文字がsecの文字列を検索

envader@172-19-2-2:~$ grep ^sec secrets.txt
secret=4c8136aba4ba90eceb3206fb8dc53be0
# $を使って、行末の文字が0(ゼロ)の文字列を検索

envader@172-19-2-2:~$ grep 0$ secrets.txt

sacret=191d9d9945545e6e6952a92a0ed14600
sacret=c37acb3ec4956548c8bbfe294222c290
sacret=c25dbd74ef7bfd0299488f6b1beb72a0
secret=4c8136aba4ba90eceb3206fb8dc53be0
sacret=59c9ab0073053950ad1e9326b019c540
sacret=29c9ea4a414d7f04e324ee7742034460
sacret=9a944d408eb76d2470bc71ea1881aca0
sacret=bad330089227df997a2cd9667ffa0ed0
sacret=c6c3ba38e00a3ec2304596733fa26a00

私がハマってしまったのがここ。
行頭を検索する時には^aとして特殊文字を先頭に持ってきていましたが、同じように$aとすると何も表示されない。。。。

なぜかと思ったら、$を使って行末を検索対象にする時にはa$としないといけないという事だったのです。

焦った。。。
でも勉強になりました。

*を使って繰り返しの文字列を検索

# 行頭の文字がseで始まって、cが0回以上繰り返す文字を検索

envader@172-19-2-2:~$ grep ^sec* secrets.txt

searet=531a5a8fff0e7cbd4031f03eec7e2784
secret=4c8136aba4ba90eceb3206fb8dc53be0

この*の理解が少し難しい。
0回以上だから、cが一つでもあると繰り返していると解釈されて表示されるってことでしょうか。
いろいろ試してみましたが、その理解で合っていそうです。

まとめ

grepコマンドと正規表現を使うことによって、より詳細にファイルやディレクトリを検索できることが分かりました。

ただ、*の検索の使い方がイマイチ理解できていないため、今後もEnvaderを利用して繰り返し学習を進めていきます。
正規表現を使いこなすことで、今後プログラミング言語を使って開発をしていく上でも必ず役に立つはず。

Envaderを使うことで、自分のPC環境を使う訳ではないので、ミスったとしても再起動すれば済むのでかなり重宝しています。

最後まで読んでいただきありがとうございました。

Discussion