仅字母排序(原为:Emacs 中的奇怪文件排序与我的语言环境有关)

Letter-only collation (was: Weird file ordering in Emacs dired with my locale)

我刚注意到。这令人毛骨悚然。但这是我的截图。所以也许可以帮助我!

TL;DR

问题在底部。

症状

  -rw-r--r--  1 jb jb  24287 mars  21  2012 array.c
  -rw-r--r--  1 jb jb  28767 oct.   1  2014 arrayfunc.c
  -rw-r--r--  1 jb jb   2895 mai   11  2012 arrayfunc.h
  -rw-rw-r--  1 jb jb   4030 mars  29  2009 array.h
-UUU:%%--F1  bash-4.3.30          6% L9     (Dired by name)---------------------
 

(这是一个 emacs -nw 屏幕截图。是的,我的终端有 6 行高。它使屏幕截图更切题。语言环境是法语,这是预期的。它与英语,想象一下有一个“may”而不是 «mai» 并且月份被大写并截断为三个字符)

万一你错过了,它是 dired 模式,文件应该按名称排序(在模式行中这样说)但 array.carray.h 不是在一起!

恐慌

我正在寻找 array.c,光标在下方所以 哇哦老兄 一分钟前它在哪里。然后我真的找到了。然后我检查模式行。然后我去 WTF 我问 SO。然后我注意到它是法语,他们永远不会更好地理解用 LC_ALL=C.

截取新的屏幕截图

但这解决了问题。

(是的,真的发生了。)

所以这是一个语言环境问题

我的语言环境是 fr_FR.UTF-8

     $ ls ar*           |       $ LC_ALL=C ls ar*
     array.c            |       array.c          
     arrayfunc.c        |       array.h          
     arrayfunc.h        |       arrayfunc.c      
     array.h            |       arrayfunc.h      

(那是我认真删除 tag and start wondering if anyone actually follows 的时候)

似乎是常态

我将为您省去神秘的 shell 调用,但要点是:在我在这里安装的 29 个语言环境中,除三个外,其他语言环境都使用“奇怪”的顺序。这三个是:C、C.UTF-8 和 POSIX.

这是不言而喻的,但无论如何提及它也没什么坏处:“奇怪”的排序让我感到不安,但它以自己的方式有意义:在这个小样本集上,它像往常一样按字典顺序排序,只是忽略了时期。所以 arrayc < arrayf < arrayh.

问题

为什么?为什么? 为什么??? 除了 C 之外的每个语言环境都有它,所以它是故意的。这是基于什么规则?某个委员会中是否有人竖立并定罪:“整理时不得遵守标点符号”?可能有一些合法的严肃文件,他们说这是完全正常的,这就是为什么,对吗?

这么多年来我还是第一次注意到。

当然,它也会忽略空格。

奖励: 这是来自 gnu.org 的 bash-4.3.30 tarball。为什么有的文件是0664,有的是0644?在评论中保留答案。
另外: 我不是在问如何修复它。如果您没有注意到,我 已经修复 并不真的需要修复它。另外,这到处都有骗局。我问的是为什么。

答案:Unicode 联盟得出结论,无论 'variable' 个字符如何,保证排序顺序比包含字符串中的每个字符更重要.

详情:我相信您正在寻找的答案位于:

Unicode Technical Standard #10: Unicode Collation Algorithm

如果我理解正确,标点符号(除其他外,如空格)在语言中是 'variable',因此为了确保跨语言的排序顺序相同,给出了 'variable' 个字符排序非常低 'weight';经常解析为零权重,因此对排序根本没有影响。

UTS 确实表明可以为每个用户自定义排序。

不幸的是,大多数系统只使用默认值,这导致只有少数排序规则定义赋予 'variable' 个字符同等权重;并且没有真正支持用户调整默认值,以便他们获得包含标点符号和空格而不是排除的 UTF-8 排序。

如果我正确地遵循了理性,请考虑对名称进行排序。在许多文化和语言中,名字总是在姓氏之前给出,当颠倒时,姓氏与名字用标点符号分隔。在其他文化中,情况正好相反。

lastname, firstname
lastname firstname

firstname lastname
firstname, lastname

为确保每个列表始终按相同顺序排序,标点符号将被忽略。