2016-05-15 4 views
2

J'écris un script qui exécute des scripts stockés dans un répertoire donné, basé sur un tableau contenant les noms de fichiers des scripts. Voici une section de mon « menu », juste pour préciser:
Expressions régulières Bash: Correspondance des nombres 0-1000

####### 

Title: Test script 1 
Description: Test script 1 
To execute: 0 

####### 

Title: Test script 2 
Description: Test script 2 
To execute: 1 

####### 

J'ai un tableau tableau nommé qui contient les noms des scripts avec un indice correspondant à la valeur imprimée sous « pour exécuter ». À l'heure actuelle, j'utilise une déclaration de cas pour gérer les entrées et fournir une option de sortie.

case $REPLY in 
    [Ee]) clear 
      exit;; 
    [[:digit:]] $scriptDirectory/${array[$REPLY]} 

Cependant, l'expression [[: digit:]] correspond uniquement à 0-9. J'ai besoin d'une regex qui fonctionne dans l'instruction case correspondant à 0-999, ou similaire.

+0

'/ \ b ([1-9] [0-9] [0-9] | [1-9] [0 -9] | [0-9]) \ b/' – YOU

Répondre

0

Dans ce cas simple, je vous suggère d'utiliser quelque chose comme ci-dessous:

REPLY="$1" # I assumed there is an argument to the script 

if [[ $1 =~ ^[[:digit:]]+$ ]] 
then 
    padded_REPLY=$(printf "%04d" "$REPLY") 
    #echo "Padded reply : $padded_REPLY" 
else 
    padded_REPLY="$REPLY" 
    echo "Padded reply : $padded_REPLY" 
fi 

regexp1="^[[:digit:]]{4}$" #checks padded_REPLY is in the range 0000 to 1000 
#the input is padded 
regexp2="[eE]+$" 

if [[ "$padded_REPLY" =~ $regexp1 ]] 
then 
    if [ "$REPLY" -le 1000 ] #checking script exist 
    then 
    echo "$REPLY" # I just echoed, you do the stuff below 
    #"$scriptDirectory/${array[$REPLY]}" 
    else 
    echo "Scripts are numbered from 0 to 1000" 
    fi  
elif [[ "$padded_REPLY" =~ $regexp2 ]] 
then 
    clear 
    exit 
fi 

Mais getopts est suggéré à la gestion des arguments plus intelligents.

3

case utilise uniquement globs (également appelés modèles d'extension de nom de fichier), et non des expressions régulières.

Vous pouvez définir extended glob avec shopt -s extglob, vous pouvez utiliser +() pour correspondre un ou plusieurs occurrence:

shopt -s extglob 

case $REPLY in 
    [Ee]) clear 
      exit;; 
    +([[:digit:]])) $scriptDirectory/${array[$REPLY]};; 
esac 

Note: j'ai ajouté manquant ) après votre deuxième motif de cas et manquant ;; au fin de la même ligne. Également ajouté l'instruction manquante esac.

Mise à jour:

Si vous voulez juste faire correspondre un nombre entre 0 et 999, essayez ceci:

 [0-9]?([0-9])?([0-9])) $scriptDirectory/${array[$REPLY]};; 

Plage de caractères sont utilisés ici que je trouve un peu plus lisible. Le résultat sera le même.

+0

nice :) Vous pourriez mentionner que le code original a aussi quelques problèmes de syntaxe .. – sjsam

+0

Merci @sjsam. J'ai mis à jour ma réponse. – SLePort

+0

Bonne réponse, merci pour les corrections aussi. J'utilisais auparavant regex, ce qui explique pourquoi ça n'a pas marché. –

2

La façon la plus simple que j'ai trouvé est bash est:

^(1000|[0-9]{1,3})$ 

En utilisant cette regex combiné avec l'opérateur =~ (qui interprète la chaîne à droite comme une expression régulière étendue ), vous pouvez Construire un test simple.(Avec votre entrée comme "$1")

if [[ $1 =~ ^(1000|[0-9]{1,3})$ ]]; then 
    echo "0 <= $1 <= 1000 (1)" 
else 
    echo "$1 - invalid number" 
fi 

Exemple d'utilisation/sortie

$ for i in -10 -1 0 1 10 100 999 1000 1001; do ./zero1thousand.sh $i; done 
-10 - invalid number 
-1 - invalid number 
0 <= 0 <= 1000 
0 <= 1 <= 1000 
0 <= 10 <= 1000 
0 <= 100 <= 1000 
0 <= 999 <= 1000 
0 <= 1000 <= 1000 
1001 - invalid number 
0

donner un essai à ceci:

case $REPLY in 
    [Ee]) 
     clear 
     exit 0;; 

    [[:digit:]]|[[:digit:]][[:digit:]]|[[:digit:]][[:digit:]][[:digit:]]|1000) 
     $scriptDirectory/${array[$REPLY]} 
     exit 0;; 
esac 

Le impliqué modèle liste correspond à 1 chiffre ou 2 chiffres ou 3 chiffres ou 1000.

Le modèle utilisé avec case est décrit dans Pattern Matching Notation du groupe ouvert.

Veuillez noter qu'il ne s'agit pas d'une expression régulière.

Il y a au moins une chose tirée de l'expression régulière; c'est le [] (RE Bracket Expression). Il est utilisé pour correspondre à un seul caractère. Donc, [[:digit:]] est valide. Il correspond à un seul caractère qui pourrait être n'importe quel chiffre.

Pour faire correspondre plusieurs chiffres, il est nécessaire de concaténer plusieurs motifs correspondant à un seul caractère, par ex. utilisez [[:digit:]][[:digit:]] pour faire correspondre 2 chiffres.

| peut être utilisé pour faire correspondre plus d'un modèle . Pour faire correspondre un nombre compris entre 0 et 99, soit un chiffre ou deux chiffres, utilisez [[:digit:]]|[[:digit:]][[:digit:]]