Возможно ли сопоставить несколько условий в одном операторе case?

Возможно ли сопоставить несколько условий в одном операторе case?

Я хотел бы сделать что-то вроде этого, чтобы в пятницу вывод был для обоих условий, которые соответствуют:

#!/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

Приведенный выше код будет выведен только в пятницу:

Вт|Ср|Чт|Пт

Желаемый результат в пятницу:

Вт|Ср|Чт|Пт
Пт|Сб|Вс

Я понимаю, что обычно,только команды, соответствующие первому шаблонукоторые соответствуют выражению, выполняются.

Есть ли способ выполнить команды для дополнительных совпадающих шаблонов?

EDIT: Я не ищуповедение при падении, но это тоже приятно знать. Спасибо steeldriver.

решение1

Вы можете использовать ;;&союз. From 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 заключается в том, что выполняется только один соответствующий сегмент. За исключением fall-through, который вы отклоняете. Кроме того, он работает только в некоторых оболочках, а не во всех, и имеет синтаксис, специфичный для каждой оболочки. Синтаксис Bash для fall-through — ;;&. В ksh или zsh единственный доступный ;&не выполняет следующий тест, а только напрямую выполняет сегмент (выводит обе строки для всех случаев в Tue|Wed|Thu|Fri).

Единственный вариант для случая — разделить его двумя строками:

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

Связанный контент