使用Unix Sort对科学计数法进行排序

20

我尝试使用Unix sort对这些数字进行排序,但似乎无效:

    2e-13
    1e-91
    2e-13
    1e-104
    3e-19
    9e-99

这是我的命令:

sort -nr file.txt

如何正确地做到这一点?


3
使用Python的sorted函数,key参数可用lambda函数指定排序依据为浮点类型。Python适合编写单行代码。预装的Python版本是什么? - Hamish Grubijan
@Hamish Grubijan - 你可能应该把它发布为一个答案,+1。这比依赖GNU扩展更具可移植性。 - Tim Post
4个回答

42

使用-g(长格式为--general-numeric-sort)代替-n-g选项通过strtod传递数字以获取其值,并将识别此格式。

我不确定这是否适用于所有的sort实现,还是仅适用于GNU实现。


1
我非常确定它最初是以GNU为中心的,但现在我想不出任何没有它的sort。这可能会有问题,但我认为只会在非常旧的系统上。 - Tim Post
2
这个程序没有正确地对0和0.1进行排序。我不得不在管道中添加LANG=C,即... | LANG=C sort -g - user3132194

8
如果你的sort命令没有-g选项,还有另一种方法。
$ printf "%.200f\n" $(<file) |sort -n |xargs printf "%g\n"
1e-104
9e-99
1e-91
3e-19
2e-13
2e-13

$ sort -g file
1e-104
9e-99
1e-91
3e-19
2e-13
2e-13

$ printf "%.200f\n" `cat file` |sort -n |xargs printf "%g\n"

7

只需要做两件事:

  1. 使用-g(或--general-numeric-sort)使sort正确处理指数数字。
  2. 使用LC_ALL=C。如果您的数据可能包含除ASCII外的一些语言特定符号,则sort对区域设置非常敏感。因此,对于您使用sort的每种情况,使用LC_ALL=C是通用方法,它使sort将输入流视为二进制,您将不会遇到任何问题。

因此,通用解决方案是:

cat file.txt | LC_ALL=C sort -gr | less

我还在我的.bashrc文件中为sort创建了一个别名:

alias csort="LC_ALL=C sort"

以便更加方便地使用。


1

好的,这里是一个未经完全测试的Python脚本版本。预期用法:

sort_script.py file.txt

很不幸,我是在Windows上开发的,并且安装了两个不同版本的Python,因此无法进行适当的测试。警告:需要最新的Python(带有添加或更改的print函数)。注意:back_to_file标志可以作为可选参数,尽管在Unix中您始终可以重定向...即使在Windows中也可以。

#!/usr/bin/env python3.1
# Note: requires newer python

import sys

#Remove this line:
sys.argv = ('', 'file.txt')

assert(len(sys.argv) == 2)

with open(sys.argv[1], 'r') as fin:
    lines = fin.readlines()

lines_sorted = sorted(lines, key=lambda x: float(x))

back_to_file = False # Change this if needed

if back_to_file:
    with open(sys.argv[1], 'w') as fout:
        fout.writelines(lines_sorted)
else:
    for lns in lines_sorted:
        print(lns, end='') # Suppress new line

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接