这是一个家庭作业问题:
匹配所有包含 2 个或更多以小写字母开头但不以大写字母结尾的字符的文件名。
我不明白为什么我的解决方案不起作用。
所以我执行了以下操作:
touch aa
touch ha
touch ah
touch hh
touch a123e
touch hX
touch Ax
ls [a-z]*[!A-Z]
输出:
aa ha
我的问题:为什么它不匹配“ah”、“hh”或“a123e”?
答案1
这是一个语言环境问题。在您的语言环境中,[A-Z]
扩展为类似的内容[AbBcZ...zZ]
(可能还加上其他重音字符),因此[^A-Z]
实际上意味着“在您的示例中以”结尾的文件a
(并且仅在您的示例中)。
如果您想避免这种意外,一种方法是设置,LC_COLLATE=C
因为排序规则是区域设置中负责排序顺序的部分。另外,LC_ALL
如果已设置,则为空,因为它会优先。
$ ls [a-z]*[^A-Z]
aa ha
$ ( LC_ALL=; LC_COLLATE=C; ls [a-z]*[^A-Z] )
a123e aa ah ha hh
或者,更好的是,最好不要更改您的区域设置并使用适当的类:[:lower:]
代替[a-z]
和[:upper:]
代替[A-Z]
。
$ ls [[:lower:]]*[^[:upper:]]
a123e aa ah ha hh
或者使用 bash 的globasciiranges
选项:
$ shopt -s globasciiranges
$ ls [a-z]*[^A-Z]
a123e aa ah ha hh
$ shopt -u globasciiranges
$ ls [a-z]*[^A-Z]
aa ha