为什么 `ls` 以看似不同的顺序列出以下文件?

Tim*_*Tim 4 ls sort locale

为什么ls以看似不同的顺序列出以下文件?

默认情况下,不会ls按照我当前语言环境的字典顺序列出文件,我猜这是默认设置吗?

$ ls
a_1  a_10  a_11  a_12

$ ls
a_10-18  a_11-18  a_1-18  a_12-18
Run Code Online (Sandbox Code Playgroud)

我有alias ls='ls --color=auto'LC_COLLATE="en_US.UTF-8"

roa*_*ima 5

语言环境真的很复杂。目的是让非技术用户“感觉正常”。(技术人员可以LANG=C用来获得那种温暖的模糊感觉。)技术定义是一个Unicode 标准文档,我试图在这里提炼出其中的一些内容。高兴地收到了更正。

我发现语言环境是处理数据的用户的属性,而不是数据本身的属性,这一点很有趣。尽管示例字符串中使用的字符相同,但该技术文档参考德国用户的排序顺序与瑞典用户的排序顺序不同,对此进行了一些详细说明。

en_GB 和 en_US 语言环境设置为忽略该-字符。非常简化,这些语言环境的升序排序规则是:

  1. 大小写不敏感
  2. 如果您有两个字符串,其中一个相同但更长,则排序第二。所以xyzA总是在xyz
  3. 某些标点符号(在这种情况下包括-)将被忽略,除非与其他标点符号进行比较
  4. 数字在字母之前排序
  5. 数字排序0..9
  6. 字母排序[Aa].. [Zz](en_GB 和 en_US 没有真正的重音)
  7. 标点符号已排序(但与此答案中的示例无关)

将这些规则应用于相关数据集:

a_1  a_10  a_11  a_12
Run Code Online (Sandbox Code Playgroud)

这等价于a1 a10 a11 a12,并且给定规则#2,我们得到它a1必须在a10和之前a11。除了a1具有相同数量的字母数字字符外,所有内容都可以进行一致的比较。这给了我们a_1 a_10 a_11 a_12.

a_10-18  a_11-18  a_1-18  a_12-18
Run Code Online (Sandbox Code Playgroud)

相同的规则适用,除了 #3 也适用(我们忽略标点符号)。这意味着我们可以将这些值视为a_1018 a_1118 a_118 a_1218,并遵循规则 #2 和 #4 我们得到顺序a_10-18 a_11-18 a_1-18 a_12-18

以评论中的最后一个例子为例

a_10 a_10- a_100 a_101 a_10-18 a_102
Run Code Online (Sandbox Code Playgroud)

规则#3,然后#2,#4 适用。所以我们删除(忽略)-给我们的字符a_10 a_10 a_100 a_101 a_1018 a_102,并按公共子串前缀然后按字符顺序对余数进行排序。

(我不清楚我们是否因为长度而得到a_10然后a_10-,或者仅仅因为它恰好以这种方式结束。我很想建议后者,但我希望有人证实这一点。)