什么是排序工具中的字母顺序?

3

我自称为 POSIX shell 大师,但今天我却失策了。

所以这里没有什么奇怪的:

bash# printf 'v10\nv1.' | sort
v1.
v10

因为.的代码为0x2e,而0的代码为0x30。但是这句话的意思是什么:

bash# printf 'v101\nv1.1' | sort
v101
v1.1

什么?好的,我是一名巫师:

$ locale

LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME=en_DK.utf8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

所以:
bash# printf 'v101\nv1.1' | LC_ALL=C sort
v1.1
v101

如何通过语言环境/排序规则使得"v101" < "v1.1"

我认为en_US.UTF-8语言环境有排序规则可以忽略.符号。这个测试表明我的看法是正确的:

bash# printf 'v102\nv1.01' | LC_ALL=en_US.UTF-8 sort
v1.01
v102

bash# printf 'v102\nv1.03' | LC_ALL=en_US.UTF-8 sort
v102
v1.03

我说的对吗?如果我说的对,那么谁不喜欢点呢?UTF-8或英语人士或美国人吗?

这是符合POSIX标准的行为吗?


是的,在比较时忽略一些字符是有效的。稍微相关的 WTF 时刻:http://stackoverflow.com/questions/34225675/weird-character-range-behaviour-with-locales-in-sed-regex-on-cygwin - Karoly Horvath
请告诉我你的回忆录将会被命名为“好的,我是巫师”,其中一章节标题为“今天我拉屎在裤子里”。+1 - pilcrow
https://www.madboa.com/geek/utf8/ - hookenz
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - hookenz
1个回答

2
是的,当LOCALE不是C时,点号似乎被忽略了。同样地,破折号也被忽略了。而且排序遵循区域设置。每天都会学到新东西。
matt@xen:~/dev/OTOY2$ printf "aa\nab\nac\n" | LC_COLLATE=C sort
aa
ab
ac
matth@xen:~/dev/OTOY2$ printf "aa\n.ab\nac\n" | LC_COLLATE=C sort
.ab
aa
ac

matt@xen:~/dev/OTOY2$ printf "aa\nab\nac\n" | sort
aa
ab
ac
matth@xen:~/dev/OTOY2$ printf "aa\n.ab\nac\n" | sort
aa
.ab
ac

你可能会感兴趣的是,sort命令也可以进行自然排序或数字排序。因此,使用-g或-h选项可以正确地对100、10和20进行排序。
在Linux下还有一个--debug标志。
matthewh@xen:~/dev/OTOY2$ printf 'v101\nv1.1' | sort --debug
sort: using ‘en_NZ.UTF-8’ sorting rules
v101
____
v1.1
____

我认为整个答案都包含在这份庞大的规范中: http://www.unicode.org/reports/tr10/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接