linux - 我可以使用哪些标准命令在命令行上高效地打印排序输出的前几行?

标签 linux bash unix

我基本上想要等同于

... | sort -arg1 -arg2 -... | head -n $k

但是,我的理解是排序将对整个输入进行 O(n log n)。在我的例子中,我要处理大量数据,所以运行时对我来说很重要——而且我有一个习惯,就是用各种临时文件溢出我的 tmp/文件夹。

我宁愿使用例如 O(n log k)一个堆,它可能运行得更快,并且还将工作集内存减少到 k

是否有一些标准命令行工具的组合可以高效地完成此操作,而无需我自己编写代码?理想情况下,它将支持排序命令的完整排序排序功能。排序(至少在 ubuntu 上)似乎没有手册页记录的开关来将其关闭...

最佳答案

基于以上内容,以及更多的探究,我会说我的问题的官方答案是“没有解决方案”。您可以使用专门的工具,也可以使用现有的工具和它们当前的性能,或者您可以编写自己的工具。

我正在考虑追踪分类源代码并提供补丁。与此同时,如果这个快速破解代码对任何人做与我正在做的事情类似的事情有帮助,这就是我为自己写的。不是最好的 python,而且是一个非常阴暗的基准:我将它提供给任何想提供更严格的人:

  • 256 个文件,总大小约为 1.6 G,全部位于 ssd 上,行 以\n 分隔,格式行 [^\t]*\t[0-9]+
  • Ubuntu 10.4、6 核、8 GB 内存、SSD 上的/tmp。
  • $ time sort -t^v<tab> -k2,2n foo* | tail -10000
    • 真正的 7m26.444s
    • 用户 7m19.790s
    • 系统 0m17.530s
  • $ time python test.py 10000 foo*
    • 真正的 1m29.935s
    • 用户 1m28.640s
    • 系统 0m1.220s
  • 通过diff分析,两种方法在平分上不同,其他排序顺序相同。

测试.py:

#!/usr/bin/env python
# test.py

from sys import argv
import heapq
from itertools import chain

# parse N - the size of the heap, and confirm we can open all input files
N = int(argv[1])
streams = [open(f, "r") for f in argv[2:]]

def line_iterator_to_tuple_iterator(line_i):
    for line in line_i:
        s,c = line.split("\t")
        c = int(c)
        yield (c, s)

# use heap to process inputs
rez = heapq.nlargest(N,
               line_iterator_to_tuple_iterator(chain(*streams)),
               key=lambda x: x[0])

for r in rez:
    print "%s\t%s" % (r[1], r[0])

for s in streams:
    s.close()

关于linux - 我可以使用哪些标准命令在命令行上高效地打印排序输出的前几行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14882897/

相关文章:

linux - 无法使用 expect 通过远程服务器中的 sftp 输入所有文件

linux - 运行时意外的文件结尾

c - Vfork() 和更多腐败

c++ - Visual C++ 和 *nix 环境下的编译差异

python - 按行计算匹配某些规则的两个字符之间的大文件中的总字节数

c++ - 如何使用管道同步父进程和子进程?

c++ - 在 C++ (Linux) 中使用 Matlab 库

Java EE webapp 不创建文件/文件夹

windows - 在 linux 和 windows 中创建目录的通用路径

arrays - bash 列出文件夹中的所有子目录,将它们写入数组以在菜单中使用