为什么非数字记录在排序后显示为“ 0”?


8

我想根据文件名中的数字对文件进行排序。这些是文件:

$ ls *.f
0.f  13.f  1.f  22.f  4.f  abc.f

排序结果:

$ ls *.f | sort -t. -k1n
0.f
abc.f # note this file!
1.f
4.f
13.f
22.f

我所期望的是:

$ ls *.f | sort -t. -k1n
abc.f
0.f
1.f
4.f
13.f
22.f

为什么abc.f只在之后0.f和之前显示1.f?是因为0不被数字处理sort吗?我在网上搜索,没有找到任何参考。


添加后仍然相同LC_ALL=C
nn0p

Answers:


12

原因是因为使用数字排序时,不带数字的字符串被视为零。GNU排序可以使行为正确,但是不对原因进行评论。illumos上用于SunOS排序的手册页确实提供了解释:

-n
将排序键限制为初始数字字符串,该字符串由可选的空白字符,可选的负号,零个或多个数字以及可选的基数字符和数千个分隔符(在当前语言环境中定义)组成,并按算术值排序。 空数字字符串被视为零。前导零和零上的符号不影响排序。

SUSv4和POSIX.1-2008(http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sort.html)中也指定了此行为,使用的方式与illumos手册页相同。

GNU排序还具有-g“通用数字排序”,它按浮点数而不是整数(其中空数字字符串在零之前排序)进行排序。我不确定这是副作用还是故意的。但是,请-g附带警告,因为它比慢得多-n。如果您要对大型数据集进行排序或执行用户正在等待的任何操作,则应避免使用-g


为了完整起见,您还应该提到如何sort处理具有相同密钥的两行。
kasperd

1

你可以使用-g

-g,-general-numeric-sort根据通用数值进行比较

root@virt01-ubuntu:~# ls  | sort -t. -k1g
a.txt
0.txt
1.txt
2.txt
3.txt
root@virt01-ubuntu:~#
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.