Sensibilidade a maiúsculas e minúsculas em scripts de shell

10

Considere este 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 eu inserir 'a', a saída será Letra minúscula e será a mesma para 'A' ... Como posso superar isso?

    
por Ramana Reddy 13.03.2015 / 13:27

2 respostas

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  

Para obter mais informações sobre a expressão regular em minúsculas de [az] e a expressão regular em maiúsculas de [AZ] no bash, consulte Por que a declaração do caso não é sensível a maiúsculas quando o nocasematch está desativado? .

    
por karel 13.03.2015 / 14:31
22

O problema é que o intervalo de caracteres [a-z] inclui as letras maiúsculas. Isso é explicado no manual do bash :

  

Dentro de uma expressão de colchetes, uma expressão de intervalo consiste em dois caracteres separados por um hífen. Ele corresponde a qualquer caractere único que classifica entre os dois caracteres, inclusive. Na localidade C padrão, a sequência de classificação é a ordem dos caracteres nativos; por exemplo, "[a-d]" é equivalente a "[abcd]". Em outras localidades, a seqüência de classificação não é especificada e '[ad]' pode ser equivalente a '[abcd]' ou a '[aBbCcDd]' , ou pode não corresponder a nenhum caractere ou ao conjunto de caracteres que corresponde pode até ser errático. Para obter a interpretação tradicional de expressões de colchetes, você pode usar o código de idioma "C" definindo a variável de ambiente LC_ALL como o valor "C".

Para ilustrar:

$ 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

Então, o que acontece é que na sua localidade (que não é C ), [a-c] é realmente [aAbBcC] . É por isso que você deve usar as classes de caracteres POSIX como sugerido por @karel.

    
por terdon 13.03.2015 / 14:54

Tags