金曜日に、両方の条件が一致する出力が得られるようなことをしたいと思います。
#!/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
上記のコードが書かれているとおり、金曜日の出力は次のようになります。
火|水|木|金
金曜日の希望出力:
火|水|木|金 金
|土|日
通常は理解できますが、最初のパターンに対応するコマンドのみ式に一致するものがすべて実行されます。
追加の一致パターンに対してコマンドを実行する方法はありますか?
編集: 私は探していませんフォールスルー行動ですが、それは知っておいてよかったことでもあります。steeldriver さん、ありがとうございます。
答え1
接続詞を使うことができます;;&
。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
詳しい情報(他のシェルでの同等のものを含む)については、
答え2
いいえ、case 文の基本構造では、一致するセグメントが 1 つだけ実行されます。ただし、拒否している fall-through は除きます。また、これはすべてのシェルではなく一部のシェルでのみ機能し、各シェルに固有の構文があります。fall-through の 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
答え3
別の選択肢: 関数を使用する。
$ 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