シェルスクリプトでの大文字と小文字の区別


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」と同じです...これを克服するにはどうすればよいですか?


スクリプトを投稿するときは、空白を維持するために、必ずコード形式を使用してください。また、実際の質問は何ですか?意味が
わかり

2
@Arronical不要、echoは予約語を処理できますecho if case then do
terdon 2015年

同様の問題について、ソートを扱う場合は、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  

bash での[az]の小文字の正規表現と[AZ]の大文字の正規表現の詳細については、nocasematchがオフのときにcaseステートメントで大文字と小文字が区別されないのはなぜですか?を参照してください


6
これに続いて、代わりに[0-9]を使用できます[[:digit:]]。その他の例についてはman grep、またはGoogle posix文字クラスをご覧ください。
Paddy Landau

21

問題は、文字範囲[a-z]に実際に大文字が含まれていることです。これはbashマニュアルで説明されています

ブラケット式内では、範囲式はハイフンで区切られた2つの文字で構成されます。これは、2つの文字間でソートする任意の1文字と一致します。デフォルトのCロケールでは、ソート順はネイティブの文字順です。たとえば、「[ad]」は「[abcd]」と同等です。他のロケールでは、並べ替え順序が指定されておらず、 '[ad]'は '[abcd]'または '[aBbCcDd]'と同等であるか、任意の文字またはその文字セットと一致しない場合があります。マッチは不規則かもしれません。大括弧式の従来の解釈を取得するには、LC_ALL環境変数を値「C」に設定することにより、「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]。そのため、代わりに@karelで提案されているPOSIX文字クラス使用する必要があります。


4
より正確には、に設定LC_COLLATEする必要がありCます。他のロケール設定が異なっていても問題ありません。LC_COLLATE何かに設定することCはめったにありませんが、残念ながらUbuntuがそれを行います(これが唯一の原因ではありません)。
Gilles「SO-邪悪なことをやめよう」
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.