为什么 ls 按长度对中文文件名排序?

nne*_*neo 4 ls sort unicode locale macos

我遇到了一些奇怪的行为,我无法完全理解ls中文文件名。我正在运行 macOS 13.6.1,启用了 SIP(​​无核心操作系统修改),安装了 MacPorts,并将美国英语作为主要语言。

\n

首先,在空白文件夹中运行这个小脚本来创建一些测试文件:

\n
import random\n\nrandom.seed(42)\n\nfor i in range(30):\n    n = random.randrange(3, 8)\n    fn = "".join(random.choice("\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89") for _ in range(n))\n    open(fn, "w")\n
Run Code Online (Sandbox Code Playgroud)\n

这使得 30 个文件以字符 \xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89(一、二、三)的随机组合命名。

\n

接下来,我ls -l在我的 Mac 上运行(根据手册页,版本为“macOS 13.5”):

\n
% ls -l\ntotal 8\n-rw-r--r--@ 1 brx  staff  164 Nov 25 02:41 test.py\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x89\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xba\x8c\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x80\n
Run Code Online (Sandbox Code Playgroud)\n

这些文件显然是按文件名长度排序的,但在其他方面不是在相同的长度内排序的,就好像ls将所有汉字视为完全相同一样。

\n

LANG设置为en_US.UTF-8(并且没有LC_*设置变量),所以也许这只是英文排序的问题?

\n
% LANG=zh_CN.utf-8 ls -l\ntotal 8\n-rw-r--r--@ 1 brx  staff  164 11 25 02:41 test.py\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x89\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xba\x8c\n-rw-r--r--+ 1 brx  staff    0 11 25 02:41 \xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x80\n
Run Code Online (Sandbox Code Playgroud)\n

是的,也许这只是Mac内置的ls蹩脚;让我们尝试一下 GNU Coreutils(来自 MacPorts ls (GNU coreutils) 9.4):

\n
% gls -l\ntotal 4\n-rw-r--r--+ 1 brx staff 164 Nov 25 02:41 test.py\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x89\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x80\n% LANG=zh_CN.utf-8 gls -l\n\xe6\x80\xbb\xe8\xae\xa1 4\n-rw-r--r--+ 1 brx staff 164 1125\xe6\x97\xa5 02:41 test.py\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x89\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 1125\xe6\x97\xa5 02:41 \xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x80\n
Run Code Online (Sandbox Code Playgroud)\n

除了GNU Coreutils幽默地破坏了日期显示之外,没有任何变化。唯一似乎有用的是C.utf-8

\n
% LANG=C.utf-8 ls -l\ntotal 8\n-rw-r--r--@ 1 brx  staff  164 Nov 25 02:41 test.py\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ?????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ??????????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ?????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ?????????????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ?????????????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ???????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ?????????????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ??????????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ?????????????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ??????????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ?????????????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ???????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ?????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ???????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ??????????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ?????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ?????????????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ?????????????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ??????????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ??????????????????\n-rw-r--r--+ 1 brx  staff    0 Nov 25 02:41 ??????????????????\n% LANG=C.utf-8 gls -l\ntotal 4\n-rw-r--r--+ 1 brx staff 164 Nov 25 02:41 test.py\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xb8\x89\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xba\x8c\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80\n-rw-r--r--+ 1 brx staff   0 Nov 25 02:41 \xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c\n
Run Code Online (Sandbox Code Playgroud)\n

这里发生了什么?我的 Mac 上的语言环境是否损坏?

\n

编辑:为了澄清预期的行为:我希望ls以任何合理的排序顺序对字符进行排序;一些合理的顺序是 Unicode 代码点(\xe4\xb8\x80、\xe4\xb8\x89、\xe4\xba\x8c)、数字或笔划计数顺序(\xe4\xb8\x80、\xe4\xba\x8c 、\xe4\xb8\x89),或拼音顺序(\xe4\xba\x8c、\xe4\xb8\x89、\xe4\xb8\x80,对应“er、san、yi”)。

\n

回答评论的一些额外信息(在en_US.UTF-8语言环境中):

\n
    \n
  • sort当通过管道传送到或gsort有或没有时,顺序保持不变-u

    \n
  • \n
  • 实际上我的系统上没有 C.utf-8 语言环境,这解释了为什么我得到与 C 语言环境中相同的输出,按字节值排序,每个字节呈现为?.

    \n
  • \n
  • expr \'\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89\' \'<\' \'\xe4\xb8\x89\xe4\xb8\x80\xe4\xba\x8c\'expr \'\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89\' \'>\' \'\xe4\xb8\x89\xe4\xb8\x80\xe4\xba\x8c\'expr \'\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89\' = \'\xe4\xb8\x89\xe4\xb8\x80\xe4\xba\x8c\'分别返回 1、0 和 0,无论是使用 macosexpr还是 GNU expr

    \n
  • \n
  • perl -MPOSIX -le \'print strcoll@ARGV\' -- \'\xe4\xb8\x80\' \'\xe4\xba\x8c\'输出-140是随perlmacos 还是 MacPorts 一起提供的

Sté*_*las 6

您会注意到,在相同长度的字符串中,这些字符似乎存在相对顺序,因此它们并不完全被视为等效。它不像 GNU libc 语言环境中没有定义的顺序,并且在大多数 UTF-8 语言环境中获得随机顺序,例如en_US.UTF-8

\n
$ ls -1\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\ntest.py\n$ ls -1 | sort -u\n\n\n\n\ntest.py\n
Run Code Online (Sandbox Code Playgroud)\n

您得到的排序顺序与对由具有相同主排序规则权重但不同后续权重的字符组成的字符串进行排序时得到的排序顺序相同。

\n

例如,在大多数语言环境中,eE\xc3\x89具有\xc3\xa9相同的主要权重,这是有充分理由的。例如,这就是如何St\xc3\xa9phane排序ST\xc3\x89PHANE之前Stephen,即使Stephane排序之前。St\xc3\xa9phane

\n
EeE\nee\xc3\xa9\ne\xc3\xa9E\n\xc3\xa9\xc3\xa9e\nEeee\nee\xc3\xa9e\nEe\xc3\xa9\xc3\xa9\ne\xc3\xa9Ee\n\xc3\xa9EE\xc3\xa9\n\xc3\xa9E\xc3\xa9e\n\xc3\xa9\xc3\xa9e\xc3\xa9\n\xc3\xa9\xc3\xa9\xc3\xa9\xc3\xa9\ne\xc3\xa9E\xc3\xa9\xc3\xa9\n\xc3\xa9Ee\xc3\xa9E\n\xc3\xa9e\xc3\xa9ee\nEEeeEe\neEee\xc3\xa9\xc3\xa9\nEee\xc3\xa9\xc3\xa9E\neE\xc3\xa9Eee\nEE\xc3\xa9EeE\nE\xc3\xa9E\xc3\xa9E\xc3\xa9\ne\xc3\xa9\xc3\xa9E\xc3\xa9e\neEe\xc3\xa9E\xc3\xa9\xc3\xa9\ne\xc3\xa9Eeeee\ne\xc3\xa9EeeeE\nE\xc3\xa9EeEEe\ne\xc3\xa9E\xc3\xa9\xc3\xa9\xc3\xa9e\nE\xc3\xa9\xc3\xa9E\xc3\xa9EE\n\xc3\xa9eeEEE\xc3\xa9\n
Run Code Online (Sandbox Code Playgroud)\n

(请注意,所有eE和 都\xc3\xa9具有相同的主要权重,e并且E也具有相同的次要权重)

\n

从您的结果来看strxfrm(),它看起来实际上是我们可以解码为的 ASCII 文本:

\n
\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89          004200420042000004l204l204l;\n\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c          004200420042000004l204l;04n>\n\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80          004200420042000004l;04l;04l2\n\xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c          004200420042000004n>04l204n>\n\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x80        0042004200420042000004l204l204l;04l2\n\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80        0042004200420042000004l204l;04n>04l2\n\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x89        0042004200420042000004l;04l;04l204l;\n\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89        0042004200420042000004l;04l;04l;04l;\n\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x80        0042004200420042000004l;04n>04l;04l2\n\xe4\xb8\x89\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89        0042004200420042000004l;04n>04n>04l;\n\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80        0042004200420042000004n>04l204l204l2\n\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89        0042004200420042000004n>04l204l;04l;\n\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89      00420042004200420042000004l204l;04n>04l;04l;\n\xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x80      00420042004200420042000004l;04l204l;04l204l2\n\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c      00420042004200420042000004l;04n>04l204l;04n>\n\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x80    004200420042004200420042000004l204l;04l;04n>04l;04l2\n\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89    004200420042004200420042000004l204n>04l204l204l;04l;\n\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80    004200420042004200420042000004l204n>04l;04n>04l204l2\n\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c    004200420042004200420042000004n>04l204l204l;04l;04n>\n\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89    004200420042004200420042000004n>04l;04n>04l;04n>04l;\n\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80    004200420042004200420042000004n>04n>04l204l204n>04l2\n\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c    004200420042004200420042000004n>04n>04l;04n>04l204n>\n\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80  0042004200420042004200420042000004l204l;04n>04l204l204l204l2\n\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c  0042004200420042004200420042000004l204l;04n>04l204l204l204n>\n\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x89\xe4\xb8\x80  0042004200420042004200420042000004l204l;04n>04l;04l;04l;04l2\n\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x80\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89  0042004200420042004200420042000004l204n>04l204l;04n>04l;04l;\n\xe4\xb8\x89\xe4\xb8\x80\xe4\xb8\x80\xe4\xba\x8c\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x89  0042004200420042004200420042000004l;04l204l204n>04n>04n>04l;\n\xe4\xba\x8c\xe4\xb8\x89\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xba\x8c  0042004200420042004200420042000004n>04l;04l;04n>04l;04n>04n>\n\xe4\xba\x8c\xe4\xb8\x89\xe4\xba\x8c\xe4\xb8\x80\xe4\xba\x8c\xe4\xba\x8c\xe4\xb8\x80  0042004200420042004200420042000004n>04l;04n>04l204n>04n>04l2\n
Run Code Online (Sandbox Code Playgroud)\n

你可以看到这0042可能是那些 \xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89 字符的主要权重的表示,并且对于所有 3 个字符都是相同的。然后可能有一个 0000 分隔符和看起来只有一个额外的(辅助)权重04n>04l;即,04l2对于 \xe4\xba\x8c (U+4E8C)、\xe4\xb8\x89 (U+4E09) 和 \xe4\xb8\x80 (U+4E00) )分别\xc2\xb9。

\n

我不知道为什么他们的排序顺序是这样定义的。GNU 系统的情况并非如此,在大多数语言环境中,U+4E00 到 U+9FA5 的主要权重是不同的,并且按其 Unicode 代码点的顺序排列。至少在 FreeBSD 12.4-RELEASE-p5 上也不是这样。

\n

也有可能(甚至很可能)我们在上面看到的是这些角色具有未定义的主要权重,而我们0042看到的是次要权重。这可以解释为什么我们在结果中似乎只看到每个字符的两个权重strxfrm()

\n

这意味着在比较恰好包含这些字符的字符串的第一遍中,这些字符只是为了比较的目的而被忽略。空白或标点字符通常就是这种情况,您不希望它们对顺序产生强烈影响。例如,foo-bar将在fooargh和 之间进行排序football,并且 的次要权重和进一步权重-将仅用于确定例如foo-bar和 的相对顺序。foo+bar

\n

苹果可能已经决定,由于并非每个人都同意这些字符的顺序,因此我们不妨忽略它们。

\n
\n

\xc2\xb9 有趣的是(尽管它没有阐明这个问题),19968 是 0x4E00,表明最后一个权重是基于代码点的。04l204l;04n>甚至0042在 strxfrm 字符串中似乎都是某种以 64 为基数的数字,其中 0123...lmno 作为与这些权重偏移 258(该基数中的 42)相对应的数字。

\n