为什么 `ls` 命令像这样对文件进行排序?

moo*_*t39 34 linux command-line ls sorting coreutils

当我试图对 ls 命令进行逆向工程时,我发现了一个有趣的行为。当我做3个文件,foo.pngfoopa.png,和fooqa.png,LS排序他们为foopa.pngfoo.pngfooqa.png。我也尝试过使用 .gif 扩展名,似乎是在 p 和 q 被扩展名的第一个字母和字母表中的下一个字母替换时发生的;所以在 . g如果是 g 和 h。( fooga.gif, 那么foo.gif, 那么fooha.gif)

为什么它以这种方式对输出进行排序?

xen*_*oid 53

这取决于您的语言环境的整理顺序:

>LANG=en_IE.UTF-8 ls -1 foo*
foopa.png
foo.png
fooqa.png

>LANG=C ls -1 foo* 
foo.png
foopa.png
fooqa.png
Run Code Online (Sandbox Code Playgroud)

您还可以使用 LC_COLLATE 变量代替 LANG,并使用 POSIX 语言环境代替 C 语言环境。

C 校对顺序是纯字母顺序(ASCII 顺序)。其他整理顺序(例如英语)可能会将空格和特殊字符(例如点)视为分隔符,并且单独处理“单词”或仅忽略这些分隔符(此处似乎就是这种情况)。

请注意,非 UTF-8 语言环境也使用字母 ASCII 进行排序:

>LANG=en_IE ls -1 foo*
foo.png
foopa.png
fooqa.png

Run Code Online (Sandbox Code Playgroud)

经过一些进一步的挖掘,似乎忽略标点符号是 Unicode 感知区域设置的一个共同特征,例如*.UTF-8那些。

  • @chrylis 不一定。UTF-8 文件名旨在用于本地语言,并遵守其排序规则。例如,在法语中,“de Gaulle”和“Degaulle”彼此相邻排序(空格不算数,而在其他名称中,撇号或破折号也不算),我们希望以它们命名的文件以同样的方式排序。这里的问题是点在文件名中具有自己的含义,并且预期的排序更接近字母(但恕我直言,字母对于文件名也不完美)。`ls` 中的扩展排序 (`-X) 是朝着正确方向迈出的一步。 (17认同)
  • 实际上你可以使用 LC_COLLATE 而不是 LANG。另见[这个](https://superuser.com/questions/862292/is-there-a-unicode-aware-lc-collat​​e-sort-order-which-respects-punctuation) (4认同)
  • 哎呀,这是一个糟糕的整理决定。 (4认同)
  • `ls -v` 更像是朝着正确方向迈出的一步 (3认同)