bashの複合コマンド[[ expression ]]の仕様とパターンマッチを使った条件評価について再確認しました。
※目次をクリックすると目次の下部にコンテンツが表示されます。
[ expression ]と[[ expression ]]の違い
・[ expression ]は、testコマンドの別名で、単独のコマンド。
・[[ expression ]]は、forやifなどのような複合コマンドで、パターンマッチングを使った条件評価も出来る。
●[ expression ]
・数値や文字列の比較、式の評価ファイル属性の評価などに使用。
①数値の比較の例
INTEGER1 -eq INTEGER2
INTEGER1 -ge INTEGER2
②文字列の比較の例
STRING1 = STRING2
STRING1 != STRING2
③式の評価の例
EXPRESSION1 -a EXPRESSION2 両方の式が真ならtrue
EXPRESSION1 -o EXPRESSION2 どちらかの式が真ならtrue
④ファイル属性演算子の例
-d FILE ”FILE”が存在し、かつディレクトリ
-f FILE ”FILE”が存在し、かつ通常ファイルである。
※bashのシェルスクリプト プログラミング方法メモの”制御構造([…])”も参照。
・[[ expression ]]は、forやifなどのような複合コマンドで、パターンマッチングを使った条件評価も出来る。
●[ expression ]
・数値や文字列の比較、式の評価ファイル属性の評価などに使用。
①数値の比較の例
INTEGER1 -eq INTEGER2
INTEGER1 -ge INTEGER2
②文字列の比較の例
STRING1 = STRING2
STRING1 != STRING2
③式の評価の例
EXPRESSION1 -a EXPRESSION2 両方の式が真ならtrue
EXPRESSION1 -o EXPRESSION2 どちらかの式が真ならtrue
④ファイル属性演算子の例
-d FILE ”FILE”が存在し、かつディレクトリ
-f FILE ”FILE”が存在し、かつ通常ファイルである。
※bashのシェルスクリプト プログラミング方法メモの”制御構造([…])”も参照。
[[ expression ]]の仕様の概要
●パターンマッチ
・”==”、”=!”オペレータが使用されるとその右側に記載した文字列はパターンとして認識され、パターンマッチングに使用される。
・”==”の場合、文字列がマッチするとリターン値が0で、マッチしない場合は1。”=!”の場合はその逆。
・パターンで、文字としてマッチさせたい場合はクォートする。
〇正規表現を使ったマッチング
・拡張正規表現を使用する場合は、”=~”オペレータを使う。
マッチした場合はリターン値が0、マッチしない場合は1、文法エラーの場合は2。
・拡張正規表現内のカッコ内でマッチした文字列は、BASH_REMATCH配列に保存される。
・BASH_REMATCH配列のインデックス0は、マッチした文字列全体が保存され、1以降には、括弧の順に対応する。
●注意点
・ワード分割とパス名展開(/)は行われない。
チルダ~展開(ユーザーホームディレクトリ)、パラメータと変数の展開、数値演算式((expression))の評価、コマンド置換$(command)、プロセス、クォートの除去は行われる。
・”“オペレータは、カレントロケールを使って辞書的にソートする。
●拡張正規表現を使ってパターンマッチする例
(サンプルコードの説明)
①”数値 英文字 英数字”のパターンの文字列かどうかを正規表現でチェック。
②上記①でマッチしたら文字列全体(BASH_REMATCH[0])、先頭の数値部分(BASH_REMATCH[1])、真ん中の英文字部分(BASH_REMATCH[2])、末尾の英数字部分(BASH_REMATCH[3])を表示する。
(regexp.sh)
・”==”、”=!”オペレータが使用されるとその右側に記載した文字列はパターンとして認識され、パターンマッチングに使用される。
・”==”の場合、文字列がマッチするとリターン値が0で、マッチしない場合は1。”=!”の場合はその逆。
・パターンで、文字としてマッチさせたい場合はクォートする。
〇正規表現を使ったマッチング
・拡張正規表現を使用する場合は、”=~”オペレータを使う。
マッチした場合はリターン値が0、マッチしない場合は1、文法エラーの場合は2。
・拡張正規表現内のカッコ内でマッチした文字列は、BASH_REMATCH配列に保存される。
・BASH_REMATCH配列のインデックス0は、マッチした文字列全体が保存され、1以降には、括弧の順に対応する。
●注意点
・ワード分割とパス名展開(/)は行われない。
チルダ~展開(ユーザーホームディレクトリ)、パラメータと変数の展開、数値演算式((expression))の評価、コマンド置換$(command)、プロセス、クォートの除去は行われる。
・”“オペレータは、カレントロケールを使って辞書的にソートする。
●拡張正規表現を使ってパターンマッチする例
(サンプルコードの説明)
①”数値 英文字 英数字”のパターンの文字列かどうかを正規表現でチェック。
②上記①でマッチしたら文字列全体(BASH_REMATCH[0])、先頭の数値部分(BASH_REMATCH[1])、真ん中の英文字部分(BASH_REMATCH[2])、末尾の英数字部分(BASH_REMATCH[3])を表示する。
(regexp.sh)
#!/bin/bash regexp='^([[:digit:]]+)[[:space:]]+([[:alpha:]]+)[[:space:]]+([[:alnum:]]+)' test="0123 AbCd AbCd123" if [[ $test =~ $regexp ]]; then echo ${BASH_REMATCH[0]} echo ${BASH_REMATCH[1]} echo ${BASH_REMATCH[2]} echo ${BASH_REMATCH[3]} fi
(実行結果)
$ sh regexp.sh
0123 AbCd AbCd123
0123
AbCd
AbCd123
※Perlの拡張正規表現(PCRE)ではなく、POSIXの拡張正規表現(ERE)を使用する必要があるようで、\d(数字)や\s(空白文字)の文字クラスは使用できず、[:digit:]、[:space:]、[:alpha:]などを指定しています。