![排序(默认选项和数字选项 -n 之间的区别)](https://linux22.com/image/10460/%E6%8E%92%E5%BA%8F%EF%BC%88%E9%BB%98%E8%AE%A4%E9%80%89%E9%A1%B9%E5%92%8C%E6%95%B0%E5%AD%97%E9%80%89%E9%A1%B9%20-n%20%E4%B9%8B%E9%97%B4%E7%9A%84%E5%8C%BA%E5%88%AB%EF%BC%89.png)
根据手册页,我们对排序命令的 --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
。
当指定-n
or--numeric-sort
选项时,连续的数字被视为数字(而不是单个字符),并按数字从小到大排序。
文档对细节并不完全明确,因此以下是通过实验得出的标志规则-n
:
- 以数字开头的行按数值排序(较小的数字排在前面)
- 数字行上的尾随字符不会影响数字部分,但如果数字部分相同,则尾随字符将按字母数字顺序排序。
- 以非数字开头的行将按零进行排序,然后按规则 2 排序。
观察:
$ printf %s\\n 2z 111 10 20b 20a aa2 aa10 | sort -n
aa10
aa2
2z
10
20a
20b
111
根据规则 3,行aa10
和aa2
被视为零,并按剩余字符(包括被视为字符的数字)排序。
根据规则 2,lines 2z
、20a
和20b
被视为数字,并且尾随字符仅在数字相同时才生效。
根据规则 1,所有以数字开头的行均按数值排序。
如果没有-n
标志,则按字符进行排序,其中数字字符位于字母字符之前。观察:
$ printf %s\\n 2z 111 10 20b 20a aa2 aa10 | sort
10
111
20a
20b
2z
aa10
aa2