首页 > 解决方案 > 当未提供 --stable 选项时, sort -n 是否可以预测地处理关系?如果有,怎么做?

问题描述

在这里,两行中的空格似乎3打破了数字排序并让字母排序开始,因此11< 2

$ echo -e '3 2\n3 11' | sort -n
3 11
3 2

man sort中,我读到

       -s, --stable
              stabilize sort by disabling last-resort comparison

这意味着没有 -s进行最后的比较在关系之间,因为-s不影响非关系)。

所以问题是:这个最后的比较是如何完成的?如果有必要回答问题,欢迎参考源代码。

这个答案 Unix从实验中推断出关系的排序是按字典顺序排列的。

标准/POSIX对此有什么说法吗?

标签: bashsortinglanguage-lawyerlexicographicstable-sort

解决方案


在这里,两行中的 3 之后的空格似乎破坏了数字排序并让字母排序开始

sort -n不是sort -n -k1,1 -k2,2sort -n整行(不是字段!)解释为数字,例如atoi("3 11")3。然后对这些数字进行排序。因为sort_them(atoi("3 11"), atoi("3 2"))是未排序的,因为两者都是数字3,所以最后的比较排序开始了。

这个最后的比较是如何完成的?

这个想法是整个行被比较,好像是strcmp或相似的(即。strcoll)。因为1在前2,所以strcmp("3 11", "3 2")3 11在第一位。没有选项被考虑,-n不被考虑。

如果有必要回答问题,欢迎参考源代码。

实际上,在 GNU 排序中,比较 (struct line const *a, struct line const *b) 中的 coreutils sort.c#L2653xmemcoll0会考虑整理,并且在未设置时作为后备。memcmpLC_COLLATE

我在 openbsd 排序中看到它在openbsd/sort/coll.c#L528 str_list_coll(struct bwstring *str1, struct sort_list_item **ss2)附近,但也在list_coll_offset()中,如果所有键比较相等top_level_str_coll,则调用它只是对整个进行排序线。

标准/POSIX对此有什么说法吗?

如果“this”指的是稳定排序和最后的比较,那么肯定。让我们从POSIX 排序重点中复制整个段落:

比较应基于从每行输入中提取的一个或多个排序键(或者,如果未指定排序键,则为直到但不包括终止符的整行),并且应使用当前语言环境。如果此整理顺序没有所有字符的总排序(请参阅 XBD LC_COLLATE),则应使用 POSIX 语言环境的整理顺序逐字节进一步比较任何同等整理的输入行。

鼓励实现对同等整理的行执行推荐的进一步逐字节比较,即使这可能会影响效率。如果当前语言环境的整理序列不具有所有字符的总排序(如果实现提供了一种查询方法),或者仅在语言环境名称的情况下执行附加比较,则可以通过仅执行附加比较来减轻对效率的影响与 LC_COLLATE 类别关联的名称中有一个“@”修饰符(因为没有“@”修饰符的语言环境应该具有所有字符的总排序 - 请参阅 XBD LC_COLLATE)。请注意,如果实现提供了一个稳定的排序选项作为扩展(通常是 -s),则在指定此选项时不应执行额外的比较。


推荐阅读