Чувствительность к регистру в сценариях оболочки

Рассмотрим этот скрипт 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

Если я введу "а", то получится строчная буква, и то же самое для "А"... Как мне преодолеть это?

2 ответа

Решение
#!/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  

Для получения дополнительной информации о регулярном выражении строчных букв [az] и регулярном выражении верхних регистров [AZ] в bash см. Почему оператор регистра не чувствителен к регистру, когда nocasematch выключен?,

Проблема в том, что диапазон символов [a-z] на самом деле включает заглавные буквы. Это объясняется в руководстве по bash:

Внутри выражения в скобках выражение диапазона состоит из двух символов, разделенных дефисом. Он соответствует любому отдельному символу, который сортируется между двумя символами включительно. В языковом стандарте C по умолчанию последовательность сортировки соответствует порядку собственных символов; например, '[ad]' эквивалентно '[abcd]'. В других локалях последовательность сортировки не указана, и "[ad]" может быть эквивалентно "[abcd]" или "[aBbCcDd]", либо может не соответствовать ни одному символу или набору символов, которые он совпадения могут быть даже ошибочными. Чтобы получить традиционную интерпретацию выражений в скобках, вы можете использовать локаль 'C', установив для переменной окружения LC_ALL значение 'C'.

Проиллюстрировать:

$ 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

Итак, что происходит, что в вашем регионе (который не C), [a-c] на самом деле [aAbBcC], Вот почему вы должны использовать классы символов POSIX, как предложено @karel.

Другие вопросы по тегам