É possível combinar várias condições em uma instrução case?

É possível combinar várias condições em uma instrução case?

Eu gostaria de fazer algo assim onde, na sexta-feira, a saída fosse para ambas as condições correspondentes:

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

Conforme o código acima está escrito, a única saída na sexta-feira seria:

Ter|Qua|Qui|Sex

Resultado desejado na sexta-feira:

Ter|Qua|Qui|Sex Sex
|Sáb|Dom

Eu entendo que normalmente,apenas os comandos correspondentes ao primeiro padrãoque corresponde à expressão são executados.

Existe uma maneira de executar comandos para padrões correspondentes adicionais?

EDITAR: não estou procurandocomportamento de queda, mas isso também é uma coisa boa de se saber. Obrigado Steeldriver.

Responder1

Você pode usar a ;;&conjunção. De 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.

Ex. dado

$ 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

então

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

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

$ ./myscript saturday
Fri|Sat|Sun

Para obter mais informações (incluindo equivalentes em outros shells), consulte

Responder2

Não, a estrutura básica para uma instrução case é que apenas um segmento correspondente seja executado. Exceto pelas falhas que você está rejeitando. Além disso, ele funciona apenas em alguns shells, não em todos, e possui uma sintaxe específica para cada shell. A sintaxe Bash para fall-through é ;;&. Em ksh ou zsh, o único disponível ;&não realiza o próximo teste, apenas executa diretamente o segmento (irá imprimir as duas linhas para todos os casos em Tue|Wed|Thu|Fri).

A única opção para case é dividi-lo com estas duas linhas:

esac
case $now in

Assim (por favor! Mantenha variáveis ​​em MAIÚSCULAS para variáveis ​​de ambiente):

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

Responder3

Outra opção: usar funções.

$ 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

e teste com

$ 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

informação relacionada