考虑这个 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”来说也是一样...我该如何克服这个问题?
答案1
问题在于字符范围[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]
。这就是为什么您应该使用 POSIX 字符类按照建议由@karel 代替。
答案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
有关小写正则表达式的更多信息[阿兹]大写正则表达式为[亚利桑那州]在 bash 中看到为什么当 nocasematch 关闭时,case 语句不区分大小写?。