Чутливість справи в сценарії оболонок


10

Розглянемо цей сценарій 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", вихід - це малі літери , і це те ж саме для "A" ... Як я можу це подолати?


Коли ви публікуєте скрипт, переконайтеся, що ви використовуєте формат коду, щоб зберегти пробіл. Також, яке власне питання? Я не впевнений, що ви маєте на увазі ...
AJefferiss

2
@Arronical немає потреби, відлуння може мати справу із зарезервованими словами echo if case then do.
тердон

Для подібного питання, але з питаннями сортування, дивіться askubuntu.com/questions/597924/…
Joe

Відповіді:


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  

Для отримання додаткової інформації про нижній регістр регулярного вираження [az] і верхнього регістру регулярного вираження [AZ] в bash див . .


6
Виходячи з цього, замість [0-9]вас можна використовувати [[:digit:]]. Ви можете знайти більше прикладів у класах символівman grep або позі Google .
Падді Ландау

21

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

У дужковому виразі діапазонний вираз складається з двох символів, розділених дефісом. Він відповідає будь-якому одному символу, який сортується між двома символами, включно. У локальній мові С за замовчуванням послідовність сортування є порядковим порядком символів; наприклад, "[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.


4
Точніше, вам потрібно встановити , LC_COLLATEщоб C, це нормально для інших локальних установок буде відрізнятися. Налаштування LC_COLLATEна що завгодно, але Cрідко є доброю ідеєю, але, на жаль, Ubuntu це робить (це поки не єдиний винуватець).
Жил "ТАК - перестань бути злим"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.