Case sensitive nello scripting di shell


10

Considera questo script Bash:

#!/bin/bash
echo Enter any character
read char
case $char in
    [a-z]) echo Lower case letter
            ;;
    [A-Z]) echo Upper case letter
            ;;
    [0-9]) echo Number
            ;;
    ?) echo Special char
            ;;
    *) echo You entered more than one character 
            ;;
esac

Se inserisco 'a', l'output è una lettera minuscola , ed è lo stesso per 'A' ... Come posso superare?


Quando pubblichi uno script, assicurati di utilizzare il formato del codice, per mantenere gli spazi bianchi. Inoltre, qual è la vera domanda? Non sono sicuro di cosa intendi ...
AJefferiss,

2
@Arronical non è necessario, l'eco può gestire parole riservate echo if case then do.
terdon,

Per un problema simile, ma relativo all'ordinamento
Joe

Risposte:


20
#!/bin/bash
echo 'enter any character'
read char
case $char in
[[:lower:]]) echo 'lower case letter'
    ;;
[[:upper:]]) echo 'upper case letter'
    ;;
[0-9]) echo 'number'
    ;;
?) echo 'special char'
    ;;
*) echo 'u entered more than one char' 
    ;;
esac  

Per ulteriori informazioni sull'espressione regolare minuscola di [az] e sull'espressione regolare maiuscola di [AZ] in bash, vedere Perché l'istruzione case maiuscole e minuscole quando nocasematch è disattivato? .


6
Seguendo questo, invece di [0-9]te puoi usare [[:digit:]]. Puoi trovare altri esempi man grepo classi di caratteri posix di Google .
Paddy Landau,

21

Il problema è che l'intervallo di caratteri [a-z]include effettivamente le lettere maiuscole. Questo è spiegato nel manuale di bash :

All'interno di un'espressione tra parentesi, un'espressione di intervallo è composta da due caratteri separati da un trattino. Corrisponde a qualsiasi singolo personaggio che si ordina tra i due personaggi, incluso. Nella locale C predefinita, la sequenza di ordinamento è l'ordine dei caratteri nativi; ad esempio, "[annuncio]" equivale a "[abcd]". In altre versioni locali, la sequenza di ordinamento non è specificata e '[annuncio]' potrebbe essere equivalente a '[abcd]' o '' aBbCcDd] ' oppure potrebbe non corrispondere a nessun carattere o all'insieme di caratteri che esso le partite potrebbero anche essere irregolari. Per ottenere l'interpretazione tradizionale delle espressioni parentesi, è possibile utilizzare la locale 'C' impostando la variabile di ambiente LC_ALL sul valore 'C'.

Illustrare:

$ case B in [a-c]) echo YES;;  *) echo NO;; esac
YES
$ LC_ALL=C; case B in [a-c]) echo YES;; *) echo NO;; esac
NO

Quindi, quello che succede è che nel tuo locale (che non lo è C), in [a-c]realtà è [aAbBcC]. Ecco perché dovresti usare invece le classi di caratteri POSIX come suggerito da @karel.


4
Più precisamente, è necessario impostare LC_COLLATEsu C, va bene che le altre impostazioni locali siano diverse. L'impostazione LC_COLLATEsu qualcosa, ma Craramente è una buona idea, ma purtroppo Ubuntu lo fa (non è di gran lunga l'unico colpevole).
Gilles 'SO- smetti di essere malvagio' il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.