排序(默认选项和数字选项 -n 之间的区别)

排序(默认选项和数字选项 -n 之间的区别)

根据手册页,我们对排序命令的 --numeric-sort 选项进行了以下描述。

-n, --numeric-sort
              compare according to string numerical value

我假设,通过字符串数值,我们的意思是连续比较每个字符串字符的 ASCII 值?

信息页面读取

‘-n’
‘--numeric-sort’
‘--sort=numeric’
     Sort numerically.  The number begins each line and consists of
     optional blanks, an optional ‘-’ sign, and zero or more digits
     possibly separated by thousands separators, optionally followed by
     a decimal-point character and zero or more digits.  An empty number
     is treated as ‘0’.  The ‘LC_NUMERIC’ locale specifies the
     decimal-point character and thousands separator.  By default a
     blank is a space or a tab, but the ‘LC_CTYPE’ locale can change
     this.

     Comparison is exact; there is no rounding error.

     Neither a leading ‘+’ nor exponential notation is recognized.  To
     compare such strings numerically, use the ‘--general-numeric-sort’
     (‘-g’) option.

阅读完这两篇文档后,我仍然没有看到明确解释 -n 选项使用哪种排序规则。

--numeric-sort 选项与默认选项有何不同?我天真的猜测是数字优先于字母,但我没有在文档中阅读这一点。

哪些文档明确说明了这一点,即我在哪里可以通过查阅文档找到此信息?

答案1

当您有多位数字时,sort -n请考虑全部的数字;默认情况下该文件

3
2
1
20
30

排序如下:

1
2
20
3
30

这可能不是你想要的。使用-n,您将得到:

1
2
3
20
30

数字排序还处理负数、小数点和千位分隔符(由您的区域设置确定)。如果存在尾随“非数字”文本,则在排序顺序中将忽略它。如果线开始对于非数字内容,该行将计为 0。

更准确地说,逻辑是这样的:(主)排序键是初始数字字符串。 (即“数字从每行开始”。)该字符串被定义为由可能的空格、减号、零个或多个数字,以及可能的.,(或其他)。尾随字母不考虑在内——它们是不是“数字”的一部分。如果该行不以数字开头,则被视为无形的(“空”)等于 0 的数字。(或者“数字为零的数字”。)

因此,在对“数字”进行排序后(比较使用-k给出排序键),如果还有任何剩余行,则对这些行进行排序使用默认排序。 (也就是说,1a之前1b——和1a20之前1a3。)所有的行以这种方式排序,而不是除排序键之外的行,这在这种情况下给出了一些奇怪的行为(0cookies排序 biscuits——对于二级排序,没有添加“看不见的0”)。

一般来说,-n当您确实想要对由数字组成的行(或字段)进行排序时使用。如果你有一堆不是数字的东西,或者是数字与其他字符串混合的东西,你仍然会得到一致的结果,但它可能不是你想要的。

如果您确实混合了字母和数字(以及包含两者的行),您可能更喜欢-V,它会执行以下操作:版本排序根据特别规则它将字符串划分为逻辑组件 - 但要小心,因为这会将1.10 更高1.9

答案2

默认情况下,sort使用区域设置指定的排序顺序对字符进行排序。一般来说,这非常接近 ASCII 顺序,但可能存在一些地区差异。从手册页:

***  WARNING  ***  The  locale  specified  by the environment affects sort order.
Set LC_ALL=C to get the traditional sort order that uses native byte values.

本机字节值通常表示 ASCII 值,因此数字位于大写字母之前,大写字母位于小写字母之前。但排序仍然是逐个字符的,所以10出现在前面,2因为1出现在前面2

当指定-nor--numeric-sort选项时,连续的数字被视为数字(而不是单个字符),并按数字从小到大排序。

文档对细节并不完全明确,因此以下是通过实验得出的标志规则-n

  1. 以数字开头的行按数值排序(较小的数字排在前面)
  2. 数字行上的尾随字符不会影响数字部分,但如果数字部分相同,则尾随字符将按字母数字顺序排序。
  3. 以非数字开头的行将按零进行排序,然后按规则 2 排序。

观察:

$ printf %s\\n 2z 111 10 20b 20a aa2 aa10 | sort -n
aa10
aa2
2z
10
20a
20b
111

根据规则 3,行aa10aa2被视为零,并按剩余字符(包括被视为字符的数字)排序。

根据规则 2,lines 2z20a20b被视为数字,并且尾随字符仅在数字相同时才生效。

根据规则 1,所有以数字开头的行均按数值排序。

如果没有-n标志,则按字符进行排序,其中数字字符位于字母字符之前。观察:

$ printf %s\\n 2z 111 10 20b 20a aa2 aa10 | sort
10
111
20a
20b
2z
aa10
aa2

相关内容