bash の使い方
bash で正規表現マッチのif も出来ます。
Version 3.2 くらいから、=~
によるマッチ判断ができるようになっています。
正規表現マッチで条件分岐の例
とてもかんたんなマッチングの例を見ておきましょう。
name='<h1>takuya</h1>' if [[ $name =~ takuya ]] ; then echo match fi
if の条件のなかに [[ ]]
のダブルブラケットを書くのがポイントです。正規表現はクオテーションは不要です。クオートしたら動かないので注意してね。
これで、文字列が存在したらマッチ。文字がアレば何かする事ができます。
すこし複雑な正規表現マッチ
最初の例だと単なる文字列マッチと区別がつかないので、もうすこし正規表現らしいマッチングをしてみます。
電話番号にマッチ
tel='09012345678' if [[ $tel =~ [0-9]{3}-?[0-9]{4}-?[0-9]{4} ]] ; then echo match fi
よく見る正規表現で、数字の出現と回数、特定の文字列の有無が判断できます。
ポイントは[[ ]]
のダブルブラケットの中で変数と文字列が展開され、マッチングしていることにあると思います。
つまり、[[ $name =~ ^REGEX$ ]]
は [[ STRING =~ ^REGEX$ ]]
に展開され、マッチするか判断されていると考えられます。
このことは、次に紹介する、正規表現を変数に埋める処理に関係します。
またクオートしなかったのも同じ理由であると考えられます。 [[ $name =~ "^REGEX$" ]]
のように書いてしまうと クォートを含めた"^REGEX$"
が正規表現として解釈されてしまうようです。
正規表現を変数に格納してマッチング。
正規表現を if
の中に書くのは後々のトラブルの種というか、悩みのタネになりそうです。
正規表現を変数に入れてマッチングをしてみたいと思います。
# 正規表現を変数に入れた場合
tel='09012345678' regex='[0-9]{3}-?[0-9]{4}-?[0-9]{4}' if [[ $tel =~ $regex ]] ; then echo match fi
先程の例の改造版です。ケータイ電話番号の正規表現マッチの処理で、正規表現の部分を変数regex
に格納した例になります。
前項の説明を借りると[[ $tel =~ $regex ]]
は [[ 09012345678 =~ [0-9]{3}-?[0-9]{4}-?[0-9]{4} ]]
に展開され、その後 [[ ]]
の内部でマッチングの処理が行われていると考えると理解しやすいでしょう。
正規表現を使えば OR 記述が少し簡潔になる
if 文の中に文字列で== をいくつも列挙するのは少々しんどい。あとで読みづらいので、正規表現を使うと少し簡潔書くことも出来ます。
まぁ正規表現だから当たり前なんですけどね。簡潔な書き方なのはうれしいですね
正規表現のORを使う例
function match_test(){ printf "%-18s: " "$1" if [[ $1 =~ apple|pen ]]; then echo match else echo dose not match fi } match_test "Hello world." match_test "This is a apple." match_test "This is pen." match_test "This is a boy."
# 上記の実行結果
Hello world. : dose not match This is a apple. : match This is pen. : match This is a boy. : dose not match
大文字・小文字の区別
正規表現を使う上で、重要になるのが大文字小文字の区別になります。Case Sensitive か Case Insensitive かは、正規表現を使う上で避けて通れない知識になります。bash では正規表現を使うときにshopt
で設定されたシェルのオプションフラグを参照してます。
# シェルのオプションの確認
$ shopt | grep case nocaseglob on nocasematch off
わたしの場合、正規表現はCase Sensitive、GlobではCase Insensitiveで利用しています。ご自身で好きな設定をすることが出来ます。もし設定を常時有効にしたい場合は、下記のコマンドを~/.bashrc
に記述しておけば設定を永続化出来ます。shopt
の使い方は別に記事を書くのでそちらも参考してください・
# 大文字小文字を区別しない設定 Senstive
shopt -s nocasematch
# 大文字小文字を区別する設定 Insensitive
shopt -u nocasematch
正規表現の他に比較で使えるもの
正規表現マッチの他にも、文字列の比較には色々使えます。
bashでは文字列の比較に次のようなものが使えます。
人によってシェルスクリプトでの書き方は異なるでしょうが、わたしは正規表現をbashだけで使えるのがとても気に入っています。
後方参照
マッチした文字列の後方参照で再利用する方法は、別の記事にしています。
追記
zsh の場合でも 同様にできる。 zsh も進んでますね。
追記
sh の場合は 、 expr を使う expr を使うときの記述例は別エントリに書いた → シェル ( /bin/sh ) での正規表現マッチ。 - それマグで!
まとめ
bash のコードが読みにくいと予断をもってるひとも、コレを見てbashの印象がすこし好転してくれるではないでしょうか。読者がbashを"再"発見されることに期待を寄せて。
2019-08-23
マッチした文字列の取得方法(後方参照)ついてのリンクを追加
2020-06-09追記
zsh についての記述を追加 。 exprについての記述を追加。