我遇到了一些奇怪的行为,我无法完全理解ls
中文文件名。我运行的是 macOS 13.6.1,启用了 SIP(无核心操作系统修改),安装了 MacPorts,并将美国英语作为主要语言。
首先,在空白文件夹中运行这个小脚本来创建一些测试文件:
import random
random.seed(42)
for i in range(30):
n = random.randrange(3, 8)
fn = "".join(random.choice("一二三") for _ in range(n))
open(fn, "w")
这使得 30 个文件以字符一二三(一、二、三)的随机组合命名。
接下来,我在我的 Mac 上运行ls -l
(根据手册页,版本为“macOS 13.5”):
% ls -l
total 8
-rw-r--r--@ 1 brx staff 164 Nov 25 02:41 test.py
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一一三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三三一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二一二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一一三一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三三一三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三三三三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三二三一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三二二三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二一一一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二一三三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二三三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三一三一一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三二一三二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三三二三一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一二一一三三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一二三二一一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二一一三三二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二三二三二三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二二一一二一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二二三二一二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二一一一一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二一一一二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二三三三一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一二一三二三三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三一一二二二三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二三三二三二二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二三二一二二一
这些文件显然是按文件名长度排序的,但在其他方面不是在相同的长度内排序的,就好像ls
将所有汉字视为完全相同一样。
LANG
设置为en_US.UTF-8
(并且没有LC_*
设置变量),所以也许这只是英文排序的问题?
% LANG=zh_CN.utf-8 ls -l
total 8
-rw-r--r--@ 1 brx staff 164 11 25 02:41 test.py
-rw-r--r--+ 1 brx staff 0 11 25 02:41 一一三
-rw-r--r--+ 1 brx staff 0 11 25 02:41 一三二
-rw-r--r--+ 1 brx staff 0 11 25 02:41 三三一
-rw-r--r--+ 1 brx staff 0 11 25 02:41 二一二
-rw-r--r--+ 1 brx staff 0 11 25 02:41 一一三一
-rw-r--r--+ 1 brx staff 0 11 25 02:41 一三二一
-rw-r--r--+ 1 brx staff 0 11 25 02:41 三三一三
-rw-r--r--+ 1 brx staff 0 11 25 02:41 三三三三
-rw-r--r--+ 1 brx staff 0 11 25 02:41 三二三一
-rw-r--r--+ 1 brx staff 0 11 25 02:41 三二二三
-rw-r--r--+ 1 brx staff 0 11 25 02:41 二一一一
-rw-r--r--+ 1 brx staff 0 11 25 02:41 二一三三
-rw-r--r--+ 1 brx staff 0 11 25 02:41 一三二三三
-rw-r--r--+ 1 brx staff 0 11 25 02:41 三一三一一
-rw-r--r--+ 1 brx staff 0 11 25 02:41 三二一三二
-rw-r--r--+ 1 brx staff 0 11 25 02:41 一三三二三一
-rw-r--r--+ 1 brx staff 0 11 25 02:41 一二一一三三
-rw-r--r--+ 1 brx staff 0 11 25 02:41 一二三二一一
-rw-r--r--+ 1 brx staff 0 11 25 02:41 二一一三三二
-rw-r--r--+ 1 brx staff 0 11 25 02:41 二三二三二三
-rw-r--r--+ 1 brx staff 0 11 25 02:41 二二一一二一
-rw-r--r--+ 1 brx staff 0 11 25 02:41 二二三二一二
-rw-r--r--+ 1 brx staff 0 11 25 02:41 一三二一一一一
-rw-r--r--+ 1 brx staff 0 11 25 02:41 一三二一一一二
-rw-r--r--+ 1 brx staff 0 11 25 02:41 一三二三三三一
-rw-r--r--+ 1 brx staff 0 11 25 02:41 一二一三二三三
-rw-r--r--+ 1 brx staff 0 11 25 02:41 三一一二二二三
-rw-r--r--+ 1 brx staff 0 11 25 02:41 二三三二三二二
-rw-r--r--+ 1 brx staff 0 11 25 02:41 二三二一二二一
是的,也许这只是Mac内置的ls
蹩脚;让我们尝试一下 GNU Coreutils(来自 MacPorts,ls (GNU coreutils) 9.4
):
% gls -l
total 4
-rw-r--r--+ 1 brx staff 164 Nov 25 02:41 test.py
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一一三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三三一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二一二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一一三一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三三一三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三三三三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三二三一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三二二三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二一一一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二一三三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二三三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三一三一一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三二一三二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三三二三一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一二一一三三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一二三二一一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二一一三三二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二三二三二三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二二一一二一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二二三二一二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二一一一一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二一一一二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二三三三一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一二一三二三三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三一一二二二三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二三三二三二二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二三二一二二一
% LANG=zh_CN.utf-8 gls -l
总计 4
-rw-r--r--+ 1 brx staff 164 1125日 02:41 test.py
-rw-r--r--+ 1 brx staff 0 1125日 02:41 一一三
-rw-r--r--+ 1 brx staff 0 1125日 02:41 一三二
-rw-r--r--+ 1 brx staff 0 1125日 02:41 三三一
-rw-r--r--+ 1 brx staff 0 1125日 02:41 二一二
-rw-r--r--+ 1 brx staff 0 1125日 02:41 一一三一
-rw-r--r--+ 1 brx staff 0 1125日 02:41 一三二一
-rw-r--r--+ 1 brx staff 0 1125日 02:41 三三一三
-rw-r--r--+ 1 brx staff 0 1125日 02:41 三三三三
-rw-r--r--+ 1 brx staff 0 1125日 02:41 三二三一
-rw-r--r--+ 1 brx staff 0 1125日 02:41 三二二三
-rw-r--r--+ 1 brx staff 0 1125日 02:41 二一一一
-rw-r--r--+ 1 brx staff 0 1125日 02:41 二一三三
-rw-r--r--+ 1 brx staff 0 1125日 02:41 一三二三三
-rw-r--r--+ 1 brx staff 0 1125日 02:41 三一三一一
-rw-r--r--+ 1 brx staff 0 1125日 02:41 三二一三二
-rw-r--r--+ 1 brx staff 0 1125日 02:41 一三三二三一
-rw-r--r--+ 1 brx staff 0 1125日 02:41 一二一一三三
-rw-r--r--+ 1 brx staff 0 1125日 02:41 一二三二一一
-rw-r--r--+ 1 brx staff 0 1125日 02:41 二一一三三二
-rw-r--r--+ 1 brx staff 0 1125日 02:41 二三二三二三
-rw-r--r--+ 1 brx staff 0 1125日 02:41 二二一一二一
-rw-r--r--+ 1 brx staff 0 1125日 02:41 二二三二一二
-rw-r--r--+ 1 brx staff 0 1125日 02:41 一三二一一一一
-rw-r--r--+ 1 brx staff 0 1125日 02:41 一三二一一一二
-rw-r--r--+ 1 brx staff 0 1125日 02:41 一三二三三三一
-rw-r--r--+ 1 brx staff 0 1125日 02:41 一二一三二三三
-rw-r--r--+ 1 brx staff 0 1125日 02:41 三一一二二二三
-rw-r--r--+ 1 brx staff 0 1125日 02:41 二三三二三二二
-rw-r--r--+ 1 brx staff 0 1125日 02:41 二三二一二二一
除了GNU Coreutils幽默地破坏了日期显示之外,没有任何变化。唯一似乎有用的是C.utf-8
:
% LANG=C.utf-8 ls -l
total 8
-rw-r--r--@ 1 brx staff 164 Nov 25 02:41 test.py
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ?????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ??????????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ?????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ?????????????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ?????????????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ???????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ?????????????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ??????????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ?????????????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ??????????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ?????????????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ???????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ?????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ???????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ??????????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ?????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ?????????????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ?????????????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ??????????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ??????????????????
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 ??????????????????
% LANG=C.utf-8 gls -l
total 4
-rw-r--r--+ 1 brx staff 164 Nov 25 02:41 test.py
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一一三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一一三一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三三二三一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二一一一一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二一一一二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二三三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一三二三三三一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一二一一三三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一二一三二三三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 一二三二一一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三一一二二二三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三一三一一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三三一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三三一三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三三三三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三二一三二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三二三一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 三二二三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二一一一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二一一三三二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二一三三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二一二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二三三二三二二
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二三二一二二一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二三二三二三
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二二一一二一
-rw-r--r--+ 1 brx staff 0 Nov 25 02:41 二二三二一二
这里发生了什么?我的 Mac 上的区域设置是否损坏?
编辑:为了澄清预期的行为:我希望ls
以任何合理的排序顺序对字符进行排序;一些合理的顺序是 Unicode 代码点(一、三、二)、数字或笔划数顺序(一、二、三)或拼音顺序(二、三、一,对应于“二、三、一”)。
回答评论的一些额外信息(在en_US.UTF-8
语言环境中):
sort
当通过管道传送到或gsort
有或没有时,顺序保持不变-u
。实际上我的系统上没有 C.utf-8 语言环境,这解释了为什么我得到与 C 语言环境中相同的输出,按字节值排序,每个字节呈现为
?
.expr '一二三' '<' '三一二'
、expr '一二三' '>' '三一二'
、expr '一二三' = '三一二'
分别返回 1、0 和 0,无论是使用 macosexpr
还是 GNUexpr
。perl -MPOSIX -le 'print strcoll@ARGV' -- '一' '二'
输出-140
是否随perl
macos 或 MacPorts 一起提供。perl -MPOSIX -le 'print strcoll@ARGV' -- '一一' '二'
输出19968
这些字符的编码看起来像
$'\344\270\200\344\270\200\344\270\211'
区域设置中一一三
报告的那样,因此看起来它们已正确编码为 UTF-8。gls
C
的输出
perl -MPOSIX -le 'print unpack "H*", strxfrm$_ for @ARGV' -- '一' '一一' '二'
是:303034323030303030346c32 30303432303034323030303030346c3230346c32 303034323030303030346e3e
的输出
perl -MPOSIX -le 'print "$_\t" . unpack "H*", strxfrm$_ for <*>'
是一一三一 303034323030343230303432303034323030303030346c3230346c3230346c3b30346c32 一一三 3030343230303432303034323030303030346c3230346c3230346c3b 一三三二三一 3030343230303432303034323030343230303432303034323030303030346c3230346c3b30346c3b30346e3e30346c3b30346c32 一三二一一一一 303034323030343230303432303034323030343230303432303034323030303030346c3230346c3b30346e3e30346c3230346c3230346c3230346c32 一三二一一一二 303034323030343230303432303034323030343230303432303034323030303030346c3230346c3b30346e3e30346c3230346c3230346c3230346e3e 一三二一 303034323030343230303432303034323030303030346c3230346c3b30346e3e30346c32 一三二三三三一 303034323030343230303432303034323030343230303432303034323030303030346c3230346c3b30346e3e30346c3b30346c3b30346c3b30346c32 一三二三三 30303432303034323030343230303432303034323030303030346c3230346c3b30346e3e30346c3b30346c3b 一三二 3030343230303432303034323030303030346c3230346c3b30346e3e 一二一一三三 3030343230303432303034323030343230303432303034323030303030346c3230346e3e30346c3230346c3230346c3b30346c3b 一二一三二三三 303034323030343230303432303034323030343230303432303034323030303030346c3230346e3e30346c3230346c3b30346e3e30346c3b30346c3b 一二三二一一 3030343230303432303034323030343230303432303034323030303030346c3230346e3e30346c3b30346e3e30346c3230346c32 三一一二二二三 303034323030343230303432303034323030343230303432303034323030303030346c3b30346c3230346c3230346e3e30346e3e30346e3e30346c3b 三一三一一 30303432303034323030343230303432303034323030303030346c3b30346c3230346c3b30346c3230346c32 三三一三 303034323030343230303432303034323030303030346c3b30346c3b30346c3230346c3b 三三一 3030343230303432303034323030303030346c3b30346c3b30346c32 三三三三 303034323030343230303432303034323030303030346c3b30346c3b30346c3b30346c3b 三二一三二 30303432303034323030343230303432303034323030303030346c3b30346e3e30346c3230346c3b30346e3e 三二三一 303034323030343230303432303034323030303030346c3b30346e3e30346c3b30346c32 三二二三 303034323030343230303432303034323030303030346c3b30346e3e30346e3e30346c3b 二一一一 303034323030343230303432303034323030303030346e3e30346c3230346c3230346c32 二一一三三二 3030343230303432303034323030343230303432303034323030303030346e3e30346c3230346c3230346c3b30346c3b30346e3e 二一三三 303034323030343230303432303034323030303030346e3e30346c3230346c3b30346c3b 二一二 3030343230303432303034323030303030346e3e30346c3230346e3e 二三三二三二二 303034323030343230303432303034323030343230303432303034323030303030346e3e30346c3b30346c3b30346e3e30346c3b30346e3e30346e3e 二三二一二二一 303034323030343230303432303034323030343230303432303034323030303030346e3e30346c3b30346e3e30346c3230346e3e30346e3e30346c32 二三二三二三 3030343230303432303034323030343230303432303034323030303030346e3e30346c3b30346e3e30346c3b30346e3e30346c3b 二二一一二一 3030343230303432303034323030343230303432303034323030303030346e3e30346e3e30346c3230346c3230346e3e30346c32 二二三二一二 3030343230303432303034323030343230303432303034323030303030346e3e30346e3e30346c3b30346e3e30346c3230346e3e test.py 303033563030333830303355303033563030314d303033523030335f30303030303033563030333830303355303033563030314d303033523030335f