bash文件模式和区分大小写的范围

phy*_*nfo 2 bash shell

我在bash的文件模式中遇到了以下恕我直言的奇怪行为:

$ ls
Basic1  datei1  datie2  sdfl
$ ls [a-z]*
Basic1  datei1  datie2  sdfl
$ ls [abcdefghijklmnopqrstuvwxyz]*
datei1  datie2  sdfl
Run Code Online (Sandbox Code Playgroud)

为什么范围的模式[a-z]不区分大小写?错误或功能?

注意:

  1. bash-Option nocasegloboff(否则,上面给出的第二种模式也应该不区分大小写......):

    $ shopt nocaseglob
    nocaseglob  off
    
    Run Code Online (Sandbox Code Playgroud)
  2. 我的bash版本:

    $ bash --version
    GNU bash, Version 4.2.24(1)-release (i686-pc-linux-gnu)
    
    Run Code Online (Sandbox Code Playgroud)

GNU bash,版本4.2.24(1) - release(i686-pc-linux-gnu)

gni*_*urf 5

如果您只想要以小写字母开头的文件名,请使用

ls [[:lower:]]*
Run Code Online (Sandbox Code Playgroud)

编辑

回答F. Hauri的评论:参考手册的第3.5.8.1节说明了一切.但是在我们阅读它之前,让我们玩一点(YMMV):创建一个新的临时目录和

$ # Create lots of cool files
$ touch {a..z} {A..Z}
$ ls
a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z
$ ls [a-b]
a A b
$ # Do you get it?
$ ls [a-B]
a A b B
Run Code Online (Sandbox Code Playgroud)

所以似乎 bash的字母顺序(这里,在我的机器上,我的设置)是:

aAbBcCdDeE...
Run Code Online (Sandbox Code Playgroud)

这可能解释了为什么你得到了你的结果(看起来你的设置与我的相似).

现在,请阅读参考手册第3.5.8.1节,您将了解事情并非如此简单,排序取决于环境变量的值LC_COLLATE.

所以尝试:

$ LC_COLLATE=C
$ ls [a-b]
a b
Run Code Online (Sandbox Code Playgroud)

是啊!

道德

如果您想要小写,请不要使用,[a-z]因为这将高度依赖于本地设置.相反,使用[[:lower:]].在参考手册中,您还可以找到其他几个有用的字符类.

底线

那么,bug还是功能呢?你现在有了答案;-)

希望这可以帮助!

  • @ F.Hauri感谢您的评论.我在答案中添加了一些解释. (2认同)