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

Рассмотрите этот сценарий 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

Если я вхожу, выводом является Строчная буква, и это - то же для 'A'... Как я преодолеваю это?

10
задан 14 March 2015 в 12:04

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  

Для получения дополнительной информации о регулярном выражении нижнего регистра [a-z] и прописное регулярное выражение [A-Z] в ударе видит , Почему оператор выбора не чувствителен к регистру, когда nocasematch прочь? .

20
ответ дан 23 November 2019 в 04:15

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

В рамках выражения скобки, выражение диапазона состоит из двух символов, разделенных дефисом. Это соответствует любому отдельному символу что виды между этими двумя символами, включительно. В значении по умолчанию C локаль, последовательность сортировки является собственным символьным порядком; например, †˜ [a-d] ’ эквивалентен †˜ [abcd] ’. В других локалях не определяется последовательность сортировки, и †˜ [a-d] ’ мог бы быть эквивалентен †˜ [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 вместо этого.

21
ответ дан 23 November 2019 в 04:15

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

Похожие вопросы: