web-dev-qa-db-fra.com

Possible de correspondre à plusieurs conditions dans une déclaration de cas?

Je voudrais faire quelque chose comme celui-ci où vendredi, la sortie est pour les deux conditions correspondant à:

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

Comme le code ci-dessus est écrit, la seule sortie vendredi serait:

Mar | Wed | Thu | Fri

Sortie souhaitée le vendredi:

Mar | Wed | Thu | Fri
Ven | Sam | Soleil

Je comprends que normalement, uniquement les commandes correspondant au premier modèle correspondant à l'expression sont exécutées.

Existe-t-il un moyen d'exécuter des commandes pour des modèles assortis supplémentaires?

EDIT: Je ne cherche pas comportement en tombant , mais c'est aussi une bonne chose à savoir. Merci steeldriver.

21
MountainX

Vous pouvez utiliser le ;;& conjonction. 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. étant donné

$ 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

alors

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

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

$ ./myscript saturday
Fri|Sat|Sun

Pour plus d'informations (y compris les équivalents dans d'autres coquilles), voir

18
steeldriver

Non, la structure de base pour une déclaration de cas est qu'un seul segment correspondant est exécuté. Sauf pour l'automne que vous rejetez. En outre, cela ne fonctionne que sur certains obus, pas tous et possède une syntaxe spécifique pour chaque coquille. La syntaxe bash pour la chute est ;;&. À Ksh ou ZSH, le seul disponible ;& n'effectue pas le prochain test, seulement exécuté directement le segment (imprimera les deux lignes pour tous les cas dans Tue|Wed|Thu|Fri).

La seule option pour cas est de la diviser avec ces deux lignes:

esac
case $now in

Comme cela (s'il vous plaît!, Gardez les variables majuscules pour les variables d'environnement):

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

Un autre choix: utiliser des fonctions.

$ 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

et tester avec

$ 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