Utilisation de case pour une gamme de nombres en Bash

j'essaie de faire ce qui suit en utilisant case en Bash (Linux).

Si X est entre 460 et 660, sortie x information.

Si X est entre 661 et 800, faire autre chose.

etc.

aujourd'hui c'est ce que j'ai:

case $MovieRes in
    [461-660]*) echo "$MovieName,480p" >> moviefinal ;;
    [661-890]*) echo "$MovieName,720p" >> moviefinal ;;
    [891-1200]*) echo "$MovieName,1080p" >> moviefinal ;;
    *) echo "$MovieName,DVD" >> moviefinal ;;
esac

mais d'une façon ou d'une autre beaucoup de ceux qui sont 480p, 720p ou 1080p se terminent avec DVD à la place. La variable $MovieRes est une liste simple qui affiche, pour chaque ligne, un nombre entre 1 et 1200. Dépendre sur la valeur, case décide quel " cas " appliquer.

je voudrais savoir comment l'utiliser effectivement case pour accomplir ceci puisque c'est un peu déroutant quand on traite avec des gammes comme celle-ci.

18
demandé sur Benjamin W. 2012-09-27 08:16:46

4 réponses

en bash, vous pouvez utiliser le arithmetic expression:((...))

if ((461<=X && X<=660))
then
    echo "480p"
elif ((661<=X && X<=890))
then
    echo "720p"
elif ((891<=X && X<=1200))
then
    echo "1080p"
else
    echo "DVD"
fi >> moviefinal
26
répondu kev 2012-09-27 04:48:20

bash case l'énoncé ne comprend pas les fourchettes de nombres. Il comprend motifs de la coquille.

La suivante devrait fonctionner:

case $MovieRes in
    46[1-9]|4[7-9][0-9]|5[0-9][0-9]|6[0-5][0-9]|660) echo "$MovieName,480p" >> moviefinal ;;
    66[1-9]|6[7-9][0-9]|7[0-9][0-9]|8[0-8][0-9]|890) echo "$MovieName,720p" >> moviefinal ;;
    89[1-9]|9[0-9][0-9]|1[0-1][0-9][0-9]|1200)       echo "$MovieName,1080p" >> moviefinal ;;
    *)                                               echo "$MovieName,DVD" >> moviefinal ;;
esac

cependant, je vous recommande d'utiliser une instruction if-else et de comparer les plages de nombres comme dans l'autre réponse. case n'est pas le bon outil pour résoudre ce problème. Cette réponse est pour des fins explicatives uniquement.

23
répondu dogbane 2012-09-27 08:02:19

Juste pour le plaisir de subversion cas à faire ce que vous voulez, vous pouvez utiliser $((...))

case 1 in
    $(($MovieRes<= 460)))echo "$MovieName,???";;
    $(($MovieRes<= 660)))echo "$MovieName,480p";;
    $(($MovieRes<= 890)))echo "$MovieName,720p";;
    $(($MovieRes<=1200)))echo "$MovieName,1080p";;
                       *)echo "$MovieName,DVD";;
esac >> moviefinal
13
répondu Alvaro 2013-07-12 12:25:05

problème Similaire qui pourrait être utile à quelqu'un ... Chose supplémentaire aléatoire je viens d'essayer où il vérifie aussi qu'il s'agit d'un entier, pour moi je voulais qu'il ait une valeur prédéfinie, laisser l'utilisateur le changer, s'ils entrent les mauvaises données qu'il définit à la valeur par défaut.

    func_set_num_files(){
        echo "How many files do you want to create? (input a number 1-10000)"
        read X
        # 1, is it a number, #2 is it within max range?
        if [[ $X != *[!0-9]* ]]; then

            if ((1<=X && X<=10000)) ;then
                        echo "NUM_FILES=$X"
                        NUM_FILES=$X
                else
                        echo "Invalid input, setting to default value [ $NUM_FILES ].";sleep 3
            fi

        else
            echo "Invalid input, non-numeric values entered, setting to default value [ $NUM_FILES ].";sleep 3
        fi

    }

un autre exemple utilisant 'case' pour vérifier qu'une variable est dans une plage d'entiers:

vérifiez que $ MAX est un nombre et qu'il est entre 50-100 :

            case $MAX in
                ''|*[!0-9]*)
                    echo "The value $MAX is not a number !"
                    exit 1
                ;;
                *)
                    if [ $MAX -lt 50 ] || [ $MAX -gt 100 ] ;then
                        echo "The value $MAX is not between 50-100"
                        exit 1
                    fi
                    echo "Looks like we are good !"
                ;;
            esac
0
répondu Mike Q 2017-07-01 16:24:47