如何使 bash 的 glob 字符类区分大小写?

如何使 bash 的 glob 字符类区分大小写?

我创建了一些文件,如knob_A.pngknob_a.png,我的 Windows 队友说这导致她的应用程序出现问题。我决定调用它knob_W.png而不是knob_a.png。然后我对我们的共享服务器进行了 rsync。为了清理一切,我做了

rm knob_[a-d]*.png

knob_A.png也移除了。这作为足球棒是错误的。

两者都shopt -s nocaseglob不会shopt -u nocaseglob让它按照我想要的方式运行。

我怎样才能告诉 bash 让它的 glob 像以前一样区分大小写?

答案1

Bash 在这里区分大小写。问题在于范围内字符的排序顺序。摘自 Bash 手册 ( info bash):

范围表达式中字符的排序顺序由当前区域设置和“LC_COLLATE”shell 变量的值(如果设置)决定。

例如,在默认的 C 语言环境中,“[a-dx-z]”等同于“[abcdxyz]”。许多语言环境按字典顺序对字符进行排序,在这些语言环境中,“[a-dx-z]”通常不等同于“[abcdxyz]”;例如,它可能等同于“[aBbCcDdxXyYz]”。要获得括号表达式中范围的传统解释,可以通过将“LC_COLLATE”或“LC_ALL”环境变量设置为值“C”来强制使用 C 语言环境。

尝试做

export LC_COLLATE=C

答案2

Bash 有一个 shell 选项来保留模式匹配,这样在扩展过程中就不会忽略大小写。您可以将其添加shopt -s globasciiranges到脚本中以启用区分大小写的匹配,然后使用 将其关闭shopt -u globasciiranges。请参阅Bash 参考 - Shopt Builtin

或者,您可以使用LC_COLLATE=C其他答案中列出的方法,但请确保已将其导出到您的环境中export LC_COLLATE

相关内容