方括号内的大小写敏感


10

通常,bash globe区分大小写:

$ 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

使用方括号似乎并没有改变:

$ 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

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

$ 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

但是这些字母散布着:

$ 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

这表明连字符正在使用语言环境顺序“ AaBbCcDd”。因此:有没有办法对所有以大写字母开头的文件进行全局处理?


3
还请注意[AZ]匹配除“ z”以外的所有小写字母的陷阱!
PJTraill

Answers:


12

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

根据shopt内置的gnu手册页

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

结果,您可以

$ shopt -s globasciiranges 
$ echo [A-Z]*

使用shopt -u禁用。

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

$ ( LC_ALL=C ; printf '%s\n' [A-Z]*; )

您将获得所需的结果,并且当子外壳程序完成时,您的主外壳程序的语言环境将保持不变。

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

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

$ shopt -s nullglob;printf '%s\n' {A..Z}*

2
很好,谢谢。我不能使用,[[:upper:]]因为我实际上只想要部分字母,但这可以工作。
rosuav

1
@rosuav欢迎。还要检查sub shell选项。
George Vasiliou

“如果启用等于C语言环境” –您是说这会影响用于遍历的语言环境,没有其他影响吗?(参考链接会很有帮助-我能找到的最好的是gnu.org/software/bash/manual/html_node/Pattern-Matching.html,但是我希望列出所有shell选项的列表,但是缺少globasciiranges从gnu.org/software/bash/manual/html_node/…;问题unix.stackexchange.com/questions/227070/…也广泛地处理了这个问题。)同样从4.3版开始。
PJTraill

@PjTrail请参阅我的编辑,并带有指向所有购物场所选项的参考链接。您也可以man bash在终端中运行并搜索(使用/)globasciiranges。
George Vasiliou

LC_ALL=C printf '%s\n' [A-Z]*没有子外壳,将无法用于您的第二个解决方案?顺便说一句:有一个错字:nullblog,但是我要纠正的字符太少了。

5

您可以像这样写所有大写字母:

[ABCDEFGHIJKLMNOPQRSTUVWXYZ]*

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

[[:upper:]]*

如您所知,在使用[B-C]相同字母字母大写和小写的范围时,它们是相邻排列的(根据的排序顺序locale)。


3

在字符范围内包括“不直观”的字符(例如,在边界为大写字母的范围内包括小写字母)是由于LC_COLLATE语言环境设置所致。LC_COLLATE本来应该指示排序顺序,但是这样做的效果很差(排序字符串比语言环境所能完成的复杂得多),如果没有排序,您会更好。我建议LC_COLLATE从您的区域设置中删除。如果您正在设置LANG,或者LANGUAGE,不这样做,并设置只有那些你需要:LC_CTYPELC_MESSAGESLC_TIME

有关语言环境的更多背景,请参阅我应该将语言环境设置为什么,以及这样做的含义是什么?设置LC_ *但不设置LC_ALL

要在脚本中获得可靠的结果而不管用户的设置如何,请设置LC_ALL=C


0

组:

shopt -u nocaseglob

从bash手册页:

>     nocaseglob
>         If  set,  bash matches filenames in a case-insensitive
>         fashion when performing pathname expansion (see Pathname
>          Expansion above).

如果设置“ globasciiranges”,我不知道非ASCII字符(如utf-8)会发生什么情况


0

回声[cC] *应该做您想要的,类似[A-Za-z] *

我在这里是因为我的系统上的globbing 不再区分大小写,因此脚本的加载不再正常工作:-(


这与我所看到的相反。但是,请检查其他答案以获取建议。
rosuav
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.