Shell中通配符[a-z]为什么会匹配大写字母
在学习通配符和扩展符的时候发现了问题,[a-z]按照理论来说应该匹配所有的小写字母,但是在实际操作过程中不仅匹配小写而且同时匹配了大写的问题。
[a-z]和[A-Z]的问题
1 | $ touch a b c x y z A B C X Y Z |
从上面的例子可以看出,本来应该只显示小写子母命名的文件或者大写字母命名的文件,但是结果和想像出现了差别。
咱们先说如何解决这个问题。
问题解决方法
使用POSIX字符集
1 | [:alnum:]:匹配字面和数字字符。等同于A~Z,a~z,0~9 |
例如:
1 | # 这里注意 [:lower:] 相当于 a-z 外边还要加上 [] 来进行任意字符匹配 |
修改LC_ALL变量的值
1 | # 建议使用第一种方法 |
简单解释原因
系统通过一些环境变量设置本地偏好,通过命令locale
可以查看设置摘要。因为语系不同导致编码的顺序不同。
LANG=C:ABC…Zabc…z
zh_CN和en_US:aAbBcC…xXyYzZ
所以会出现开头的问题,由于能够设置的环境变量很多,LC_ALL是覆盖所有其他本地化设置的环境变量(在某些情况下除外$LANGUAGE)。所以一些脚本为了避免用户本地配置的干扰,通常在开头设置LC_ALL=C
。
在C语言环境中,字符是单个字节,字符集是ASCII(不是必需的,但实际上将在我们大多数人都会使用的系统中使用),排序顺序基于字节值,该语言通常是美国英语(尽管对于应用程序消息(与月份或日期名称或系统库中的消息相反),它由应用程序作者自行决定),并且未定义货币符号之类的东西。
参考资料