方括号通配中的区分大小写

ros*_*uav 14 shell bash wildcards locale

通常,bash globbing 区分大小写:

$ echo c*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo C*
CarePackage.md ChocRippleCake.md Clips
Run Code Online (Sandbox Code Playgroud)

使用方括号似乎不会改变这一点:

$ echo [c]*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo [C]*
CarePackage.md ChocRippleCake.md Clips
Run Code Online (Sandbox Code Playgroud)

如果使用连字符,它仍然不会改变它:

$ echo [c-c]*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo [C-C]*
CarePackage.md ChocRippleCake.md Clips
Run Code Online (Sandbox Code Playgroud)

但是字母是穿插的:

$ echo [B-C]*
CarePackage.md casefix.pike cdless chalices.py charconv.py chocolate.pike ChocRippleCake.md circum.py clip.pike Clips cpustats.pike crop.pike cwk2txt.py
$ echo [b-c]*
beehive-anthem.txt bluray2mkv.pike branch branchcleanup.pike burdayim.pike casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
Run Code Online (Sandbox Code Playgroud)

这表明连字符正在使用区域设置顺序“AaBbCcDd”。那么:有没有办法对所有以大写字母开头的文件进行通配符?

Geo*_*iou 13

在 bash 4.3 及更高版本中,有一个名为 的 shopt 选项globasciiranges

根据shopt 内置的 gnu 手册页

globasciiranges
如果设置,则在模式匹配括号表达式(请参阅模式匹配)中使用的范围表达式在执行比较时表现得如同在传统 C 语言环境中一样。也就是说,不考虑当前语言环境的整理顺序,因此 'b' 不会在 'A' 和 'B' 之间进行整理,并且大写和小写 ASCII 字符将整理在一起。

结果你可以

$ shopt -s globasciiranges 
$ echo [A-Z]*
Run Code Online (Sandbox Code Playgroud)

使用shopt -u禁用。

另一种方法是将语言环境更改为 C。您可以使用子 shell 临时执行此操作:

$ ( LC_ALL=C ; printf '%s\n' [A-Z]*; )
Run Code Online (Sandbox Code Playgroud)

你会得到你需要的结果,当子 shell 完成时,你的主 shell 的语言环境保持不变。

另一种选择是[A-Z]将大括号扩展{A..Z}nullglobbash shopt 选项一起使用。

通过启用该nullglob选项,如果在路径名扩展期间模式不匹配,则返回空字符串而不是模式本身。
因此,这将按预期工作:

$ shopt -s nullglob;printf '%s\n' {A..Z}*
Run Code Online (Sandbox Code Playgroud)

  • 很好,谢谢。我不能使用`[[:upper:]]`,因为我实际上只想要字母表的一部分,但这是有效的。 (2认同)

hee*_*ayl 6

你可以把所有的大写字母都写得很好,比如:

[ABCDEFGHIJKLMNOPQRSTUVWXYZ]*
Run Code Online (Sandbox Code Playgroud)

或者 use 可以使用命名字符类[:upper:]来表示当前 中的所有大写字母locale

[[:upper:]]*
Run Code Online (Sandbox Code Playgroud)

正如您所注意到的,在使用类似[B-C]大写和小写的范围时,相同的字母字符是相邻排列的(根据 的整理顺序locale)。