我基本上想要等同于
... | 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/