bash - 排序实用程序的字母顺序是什么?

标签 bash sorting posix locale collation

我称自己为 POSIX shell 向导。但是今天我拉进了裤子。

所以这没什么奇怪的:

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

因为.有代码 0x2e0有代码 0x30 .但是这个怎么样:

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

WTF?好吧,我是巫师:

$ 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

locales/collat​​ion 如何制作 "v101" < "v1.1"

我认为 en_US.UTF-8 locale 有排序规则要剥离 .符号。这个测试表明我有一点:

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 兼容行为吗?

最佳答案

是的,当 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 也可以进行自然排序或数字排序。 所以 100 10 和 20 可以在排序时使用 -g 或 -h 正确排序。

在 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/

关于bash - 排序实用程序的字母顺序是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34443738/

相关文章:

bash - 在函数内访问脚本位置参数

perl - 使用系统命令将 stdout 和 stderr 输出重定向到文件在 perl 中不起作用

java - 如何按除第一个字母以外的所有内容对字符串数组进行排序

javascript - 如何使表格可按标题 Angular 排序?

sockets - 我可以测试文件描述符的类型是否适合 read() 吗?

linux - bash:从另一个文件填充文件

bash - 将并行变量 "{}"作为 awk 变量传递

android - 如何在 Android 中排序和分组?

c - fork() 后子进程的独立 I/O

c - 是否可以对管道进行读而不是 block ,而是写 block ?