フォールスルー付きのスイッチケース?


193

Bashのフォールスルーケース(理想的には大文字と小文字を区別しない)でのswitchステートメントの正しい構文を探しています。PHPでは、次のようにプログラムします。

switch($c) {
    case 1:
        do_this();
        break;
     case 2:
     case 3:
        do_what_you_are_supposed_to_do();
        break;
     default:
        do_nothing(); 
}

私はバッシュでも同じようにしたいです:

case "$C" in
    "1")
        do_this()
        ;;
    "2")
    "3")
        do_what_you_are_supposed_to_do()
        ;;
    *)
        do_nothing();
        ;; 
esac

これはどういうわけか機能しませんdo_what_you_are_supposed_to_do()。$ Cが2 OR 3のときに関数を実行する必要があります。


4
括弧で呼び出し関数を使用しないでください!!! 関数をbashで定義しfunction fname { echo "Inside fname"; return 0; }たりfname() { echo "inside fname"; return 0; }、括弧を関数呼び出しに配置したりできるので、関数の定義のように見えます。関数は、次のような他のコマンドラインプログラムのように呼ばれるべきmvcprsynclscd、等...この場合、私たちはそうのようなfnameのを呼び出しますfname $ARGS
Charles Addis

do_nothing()SKIPステートメントにする必要がありますか?を使用し:ます。
sjas

回答:


309

|「または」には縦棒()を使用します。

case "$C" in
"1")
    do_this()
    ;;
"2" | "3")
    do_what_you_are_supposed_to_do()
    ;;
*)
    do_nothing()
    ;;
esac

30
または、この単純なケースでは、文字クラス[23])
SiegeX 2011

4
@ミシュカ-私はあなたがこの答えを受け入れていないことに気付きました、それは質問のフォールスルー部分に答えないからですか?フォールスルーロジックはdo_what_you_are_supposed_to_do()、の前に特別な処理を行う必要がある場合に役立ちます。「2」と「3」の両方を1つのケースにまとめると、これに対処できません。多くの人がこの回答が役に立ったと思っているのは明らかであるため、これをより明確にするために質問を編集することが合理的であるかどうかはわかりません。
タイソン

1
@Tyson OPは未登録のユーザーであるため、回答を受け入れませんでした。プログラマーが通常理解する「フォールスルー」ロジックに関して、質問の本文は、フォールスルーロジックではなく、条件の崩壊を示します。(お知らせの使用breakPHPコードインチ)は、この日に、ご質問、またはそのタイトルの編集は、回答の多く無効になる提供は、ロジックを介し-落ち、おそらく行われるべきではありません。フォールスルーは他のユーザーによるいくつかの編集までタイトルに含まれていませんでしたが、今それを取り戻すには遅すぎます。
user7412956

100

最近のbashバージョンでは;&、の代わりにを使用してフォールスルーを;;許可して;;&います。また、そこで使用することでケースチェックを再開できます。

for n in 4 14 24 34
do
  echo -n "$n = "
  case "$n" in
   3? )
     echo -n thirty-
     ;;&   #resume (to find ?4 later )
   "24" )
     echo -n twenty-
     ;&   #fallthru
   "4" | [13]4)
     echo -n four 
     ;;&  # resume ( to find teen where needed )
   "14" )
     echo -n teen
  esac
  echo 
done

出力例

4 = four
14 = fourteen
24 = twenty-four
34 = thirty-four

1
この例のこのロジックは、理解するのが困難でした。また、私は、この例では、実際の違いを示していないと思う;&;;&。を変更し"24";;& # resume同じ結果を得たので、;&フォールスルーをいつ使用するのかまだ疑問に思っています。
wisbucky

1
私は変更-それは複雑なもののために簡単な例です?4[13]4、それがより明確にするために、そしてあなたの変更破壊変更を行うために
Jasen

26
  • ()定義したくない場合は、bashの背後で関数名を使用しないでください。
  • [23]一致する場合に使用2または3
  • 静的な文字列の場合は''""

で囲まれている""場合、インタプリタは(不必要に)一致する前に値の可能な変数を展開しようとします。

case "$C" in
'1')
    do_this
    ;;
[23])
    do_what_you_are_supposed_to_do
    ;;
*)
    do_nothing
    ;;
esac

大文字と小文字を区別しないマッチングでは、([23])などの文字クラスを使用できます。

case "$C" in

# will match C='Abra' and C='abra'
[Aa]'bra')
    do_mysterious_things
    ;;

# will match all letter cases at any char like `abra`, `ABRA` or `AbRa`
[Aa][Bb][Rr][Aa])
    do_wild_mysterious_things
    ;;

esac

しかしabra、最初のケースと一致するため、いつでもヒットしませんでした。

必要に応じて、;;最初のケースでは省略して、次のケースでも一致のテストを続行できます。(に;;ジャンプesac


大文字と小文字case "${C,,}" inが区別されない場合は、Cを小文字に変換することもできます
Sprinterfreak

1
を省略すると;;どうなりますか?;&フォールスルーに使用するのではないですか?
HelloGoodbye 2016年

1
テストを続行したい場合に;; 使用する必要があると、構文エラーが発生し;;&ます。
Jasen 2016年

do_wild_mysterious_things私の日を作った
Julien__

14

これを試して:

case $VAR in
normal)
    echo "This doesn't do fallthrough"
    ;;
special)
    echo -n "This does "
    ;&
fallthrough)
    echo "fall-through"
    ;;
esac

1
これは非常に役立つヒントです。少なくともBash 4.3.11では。私は他の人にそれを試す気にしたことがありません。
Daniel

3
注:これは、macOSのデフォルトのbashであるbash 3.2では機能しません。
Danny Kirchmeier、2016年

13

値が整数の場合は、使用[2-3]することも[5,7,8]、非連続値に使用することもできます。

#!/bin/bash
while [ $# -gt 0 ];
do
    case $1 in
    1)
        echo "one"
        ;;
    [2-3])
        echo "two or three"
        ;;
    [4-6])
        echo "four to six"
        ;;
    [7,9])
        echo "seven or nine"
        ;;
    *)
        echo "others"
        ;;
    esac
    shift
done

値が文字列の場合は、を使用できます|

#!/bin/bash
while [ $# -gt 0 ];
do
    case $1 in
    "one")
        echo "one"
        ;;
    "two" | "three")
        echo "two or three"
        ;;
    *)
        echo "others"
        ;;
    esac
    shift
done

shiftのための終わり?
Milkncookiez

1
shiftCLI引数リストの最初の引数を削除します。基本的に、このループのすべての繰り返しで、を$1使用してCLI引数リストから各引数を取得するために常に使用されますshift
rashok
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.