Shell脚本中的区分大小写


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可以处理保留字echo if case then do
terdon 2015年

对于类似的问题,但要处理排序,请参见askubuntu.com/questions/597924/…–

Answers:


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字符类中找到更多示例。
帕迪·兰道

21

问题在于字符范围[a-z]实际上包括大写字母。bash手册对此进行了解释:

在方括号表达式中,范围表达式由用连字符分隔的两个字符组成。它与在两个字符(包括两个字符)之间排序的任何单个字符匹配。在默认的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_COLLATEC,其他语言环境设置也可以不同。设置LC_COLLATE为任何东西,但C很少是一个好主意,但可悲的是Ubuntu做到了(到目前为止,这并不是唯一的罪魁祸首)。
吉尔斯(Gilles)'“ SO-别再邪恶了”
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.