Bashテスト:「=〜」は何をしますか?


40
#!/bin/bash
INT=-5

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then

echo "INT is an integer."

else

echo "INT is not an integer." >&2

exit 1

fi

~先頭の正規表現の先頭は何をしますか?


3
これは正規表現ではなく、正規表現の一致を判断するためのテストパターンです。
jasonwryan17年

5
bashのマニュアルを読みましたか?不明な点は何ですか?
イカロス

3
=〜のために、bashのmanページを検索
ジェフ・シャラー

回答:


46

~実際にオペレータの一部であり、=~その右側に拡張正規表現への左にある文字列の正規表現マッチを行います。

[[ "string" =~ pattern ]]

文字列は引用符で囲む必要があり、正規表現は引用符で囲まないでください。

同様の演算子がPerlプログラミング言語で使用されています。

によって理解される正規表現bashは、GNU grep-Eフラグで理解する正規表現、つまり正規表現の拡張セットと同じです。


多少話題から外れていますが、知っておくと便利です。

キャプチャグループを含む正規表現と照合する場合、各グループによってキャプチャされた文字列の一部がBASH_REMATCH配列で利用可能です。この配列の0番目/最初のエントリは、置換コマンド(またはPerl)の置換&パターンに対応します。これはパターンに一致する文字列のビットであり、インデックス1以降のエントリは、などに対応します。。置換パターン(またはPerl ではなど)、つまり各括弧で一致したビット。sed$&\1\2sed$1$2

例:

string=$( date +%T )

if [[ "$string" =~ ^([0-9][0-9]):([0-9][0-9]):([0-9][0-9])$ ]]; then
  printf 'Got %s, %s and %s\n' \
    "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}"
fi

これは出力するかもしれません

Got 09, 19 and 14

現在の時間が09:19:14である場合。

配列名のREMATCHビットは、BASH_REMATCH「正規表現一致」、つまり「RE-Match」に由来します。


bashBourne風のシェルではexpr、制限された正規表現のマッチングにも使用できます(基本的な正規表現のみを使用)。

小さな例:

$ string="hello 123 world"
$ expr "$string" : ".*[^0-9]\([0-9][0-9]*\)"
123

2
これgrep -Eは、GNUシステムでのみ、パターンとして引用されていない変数を使用する場合にのみ理解されるものと同じです[[ $var = $pattern ]][[ 'a b' =~ a\sb ]]vsを参照p='a\sb'; [[ 'a b' =~ $p ]])。また、シェルの引用はRE演算子の意味に影響を与え、REの処理に影響を与える可能性のあるシェルのトークン化には一部の文字を引用する必要があることに注意してください。[[ '\' =~ [\/] ]]falseを返します。ksh93さらに悪い問題があります。zshシェルとREのクォートが明確に分離されている場合の賢明なアプローチについては(またはbash 3.1)を参照してください。の[組み込みzshおよび演算子yashもあり=~ます。
ステファンシャゼラス

2
とてもクールoff-topic!+1(
JJoao

@StéphaneChazelasこの2つがzshで一致するのはどのように「saner」ですか?:[[ "This is a fine mess." =~ T.........fin*es* ]]; [[ "This is a fine mess." =~ T.........fin\*es\* ]]。または、引用符*も一致しますか?[[ "This is a fine mess." =~ "T.........fin*es*" ]]
-sorontar

それははるかに単純なルールであるという点で、saner(IMO)です。シェルのクォートとREのエスケープは明らかに分離されています。では[[ a =~ .* ]]または[[ a =~ '.*' ]]あるいは[[ a =~ \.\* ]]、同じ.*REが渡される=~演算子。OTH、でbash[[ '\' =~ [)] ]]エラーを返し、あなたがいるかどうか、それをしようとせず知っているだろう[[ '\' =~ [\)] ]]試合?どうでしょう[[ '\' =~ [\/] ]](ksh93で行います)。どうですかc='a-z'; [[ a =~ ["$c"] ]]=オペレータと比較して)?参照してください:[[ '\' =~ [^]"."] ]]あなたがすることができるという誤った...注意を返すshopt -s compat31bash取得するためにzsh行動を。
ステファンシャゼラス

zsh/ bash -o compat31の動作[[ a =~ '.*' ]][ a '=~' '.*' ](を[サポートする実装の=~場合)またはexpr a : '.*'。OTOH、[[ a = '*' ]]vs とは一致しません[[ a = * ]](ただし、globはシェル言語の一部ですが、REはそうではありません)。
ステファンシャゼル

4

[[ expression ]]セクションの下にあるbashのmanページを読んでください。

An additional binary operator, =~, is available, with the same precedence as == and !=. When it is used, the string to the right of the operator is considered an extended regular expression and matched accordingly (as in regex(3)).

ロングストーリーショートは、=~同じように、オペレータである==!=。右側の文字列の実際の正規表現とは関係ありません。


=~実生活での使用を示すいくつかの例を理解できますか...?
ジョージヴァシリウ

1
@GeorgeVasiliouコマンドからの出力を変数に入れるスクリプトでかなり頻繁に使用します。次に、変数をチェックして、文字列パターンに一致するかどうかを確認します。これは、たとえば、そのコマンドからのエラー出力に基づいて何らかのアクションを実行する場合に役立ちます。
マイケルマルティネス

@Sokel一部の人にとって、「RTFM」は言うよりも簡単です。⋯ man [[ expresssion ]]そしてman [[何も返しません。 内部bashコマンドhelp [[から有用な情報を返します[[が、=~基本または拡張正規表現構文のどちらを使用するかは述べていません。quote引用したテキストは、bashのマニュアルページからのものです。「bashのマニュアルページを読む」と言っていたことがわかりますが、最初は、bash内のマニュアルページを読むことを意味すると思いました。とにかく、man bash4139行(72ページ)の巨大なファイルを返します。を押すと検索できます/▒▒▒が、正規表現を使用しますが、そのフレーバーは(=~たとえば)指定されていません。
アレックスクイン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.