web-dev-qa-db-ja.com

1つのケースステートメントで複数の条件に一致させることは可能ですか?

金曜日に出力が両方の条件に一致する場合、次のようなことをしたいと思います。

#!/bin/bash

#!/bin/bash
NOW=$(date +"%a")
case $NOW in
    Mon)
        echo "Mon";;
    Tue|Wed|Thu|Fri)
        echo "Tue|Wed|Thu|Fri";;
    Fri|Sat|Sun)
        echo "Fri|Sat|Sun";;
    *) ;;
esac

上記のコードが記述されているので、金曜日の唯一の出力は次のようになります。

火曜日|水曜日|木曜日|金曜日

金曜日に必要な出力:

火曜日|水曜日|木曜日|金曜日
金|土|日

通常、式に一致する最初のパターンに対応するコマンドのみが実行されることを理解しています。

追加の一致したパターンのコマンドを実行する方法はありますか?

編集:私は フォールスルー動作 を探していませんが、それも知っておくと便利です。スティールドライバーに感謝します。

12
MountainX

;;&結合。 man bash

               Using ;;& in place of ;; causes the Shell to test
the next pattern list in the statement, if any, and execute  any
associated  list on a successful match.

例与えられた

$ cat myscript 
#!/bin/bash
NOW=$(date -d "$1" +"%a")
case $NOW in
    Mon)
        echo "Mon";;
    Tue|Wed|Thu|Fri)
        echo "Tue|Wed|Thu|Fri";;&
    Fri|Sat|Sun)
        echo "Fri|Sat|Sun";;
    *) ;;
esac

その後

$ ./myscript thursday
Tue|Wed|Thu|Fri

$ ./myscript friday
Tue|Wed|Thu|Fri
Fri|Sat|Sun

$ ./myscript saturday
Fri|Sat|Sun

詳細(他のシェルの同等物を含む)については、以下を参照してください。

18
steeldriver

いいえ、caseステートメントの基本的な構造は、一致するセグメントが1つだけ実行されることです。あなたが拒否しているフォールスルーを除いて。また、すべてではなく一部のシェルでのみ機能し、各シェルに固有の構文があります。フォールスルーのBash構文は;;&です。 kshまたはzshでは、使用可能な;&は次のテストを実行せず、セグメントを直接実行するだけです(Tue|Wed|Thu|Friのすべてのケースで両方の行が出力されます)。

ケースの唯一のオプションは、次の2行で分割することです。

esac
case $now in

このように(環境変数のために大文字の変数を保持してください!):

#!/bin/bash
now=$(date +"%a")
case $now in
    Mon)
        echo "Mon";;
    Tue|Wed|Thu|Fri)
        echo "Tue|Wed|Thu|Fri";;
esac
case $now in
    Fri|Sat|Sun)
        echo "Fri|Sat|Sun";;
    *) ;;
esac
1
Isaac

別の選択:関数を使用します。

$ cat tt
#!/bin/bash

mon()     { echo "  Mon"             ; }
tue_fri() { echo "  Tue|Wed|Thu|Fri" ; }
fri_Sun() { echo "  Fri|Sat|Sun"     ; }

now=$(date +"%a")
[[ $1 != "" ]] && now=$1      # use for testing

case $now in
  Mon)         mon              ;;
  Tue|Wed|Thu) tue_fri          ;;
  Fri)         tue_fri; fri_Sun ;;
  Sat|Sun)     fri_Sun          ;;
  *)           echo "  ERROR"   ;;
esac

そしてテストする

$ for f in Mon Tue Wed Thu Fri Sat Sun bla ;do echo "$f"; tt "$f"; done
Mon
  Mon
Tue
  Tue|Wed|Thu|Fri
Wed
  Tue|Wed|Thu|Fri
Thu
  Tue|Wed|Thu|Fri
Fri
  Tue|Wed|Thu|Fri
  Fri|Sat|Sun
Sat
  Fri|Sat|Sun
Sun
  Fri|Sat|Sun
bla
  ERROR