[[およびbashの大文字小文字の同値


13

する

if [[ "$1" = pattern ]]; then
    hook
fi

常に同じように振る舞います

case "$1" in
    pattern) hook;;
esac

または何か落とし穴がありますか?


1
または、またはその後のshopt設定と値にかかわらず、それらが異なるケースは見つかりません。唯一の違いは、で実行する場合、出力で展開されないことです。$1pattern$?$1xtrace
クサラナナンダ

回答:


7

はい、それらは(ほぼ)完全に同等です。


詳細

構造内[ … ]

=オペレータ(または偶数非POSIXオプションは==)文字列照合ではなく、パターンマッチングをテストします。

[[ ]]コンストラクト内(man bashから):

==および!=演算子が使用される場合、演算子の右側の文字列はパターンと見なされ、以下のパターンマッチングで説明されているルールに従ってマッチングされます。シェルオプションnocasematchが有効な場合 、アルファベット文字の大文字小文字を区別せずに照合が実行されます。戻り値は、文字列がパターンに一致する(==)または一致しない(!=)場合は0、そうでない場合は1です。パターンの任意の部分を引用して、文字列として一致させることができます。

caseコンストラクトの内部(man bash、編集、および強調鉱山から):

[[(] pattern [| pattern] ...)リストのケースワード;; ] ... esac
...は、パス名の展開と同じマッチングルールを使用して、各パターンに対して順番にマッチングを試みます(以下のパス名の展開を参照)。…検査される各パターンは、チルダ展開、パラメータおよび変数展開、算術置換、コマンド置換、およびプロセス置換を使用して拡張されます。シェルオプションnocasematchが有効な場合、アルファベット文字の大文字小文字を区別せずに照合が実行されます。

どちらPattern MatchingPathname Expansionbashのマニュアル内で同じことを意味するために使用されています。

マニュアルで見ることができる唯一の違いは:

`[[ … ]]`                                   case
tilde  expansion                            tilde expansion
parameter and variable expansion            parameter and variable expansion
arithmetic expansion                        arithmetic substitution
command substitution                        command substitution
process substitution                        process substitution
quote removal

それquote removalは、ケース構造に対して明示的にリストされていません。
これは(これに対して[[ … ]])正確に一致するように機能します。

パターンの任意の部分を引用して、文字列として一致させることができます。

これを使用して、この最後のポイントをテストします(変数はパターンではありません):

case "$1" in
  "$pattern") echo case match
esac

なぜほとんど?

  1. 暗黙的extglob

    bashのバージョン4.3以降

    「==」および「!=」演算子が使用される場合、演算子の右側の文字列はパターンと見なされ、extglobシェルオプションが有効であるかのように、以下のパターンマッチングで説明されているルールに従ってマッチングされます

    つまり、オプションextglob unsetで使用されるパターンは、caseステートメントと[[bashバージョン4.3以降の構造内で異なる動作をします。

  2. 暗黙的|

    caseの構文は次のとおりです。

    case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac

    つまり、|(OR)で区切られた複数のパターンが存在する可能性があります。

    このような:

    shopt -s extglob;      p1="+([0-9])";       p2="+([abcde])"
    
    case "$1" in
        $p1|$p2)    echo "or case match" ; ;;
    esac

    ここで数字や文字のみのみの文字列のいずれかと一致しますabcdeように、1234aabeeではなく、12ab23

    正規表現(var p3を参照)が使用されている[[場合、A は同等に機能します。

    #!/bin/bash
    
    shopt -s extglob           ### Use extended globbing.
    shopt -s globasciiranges   ### The range [a-z] will expand to [abcdefghijklmnopqrstuvwxyz].
    
    pattern="+([0-9])"
    p1="+([0-9])"
    p2="+([a-z])"
    p3="^([0-9]+|[a-z]+)$"
    
    case "$1" in
        $pattern)   echo case1 match ; ;&
        $p1|$p2)    echo case2 match ; ;;
    esac
    
    [[ "$1" == $pattern ]] && echo if1 match
    [[ "$1" =~ $p3 ]] && echo if2 match
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.