这是一个粗略的部分解决方案:
#!/usr/bin/perl
use strict;
use warnings;
my @lines = ();
while (<>) {
push @lines, $_;
@lines = sort @lines;
if (scalar @lines > 10) {
pop @lines;
}
}
print @lines;
它只读取一次输入数据,持续维护前 10 行的排序数组。
当然,每次对整个数组进行排序是低效的,但我猜对于千兆字节的输入,它仍然会比sort huge-file | head
.
添加一个选项来改变打印的行数会很容易。添加选项来控制如何完成排序会有点困难,但如果CPAN中有一些东西可以帮助我,我不会感到惊讶。
更抽象地说,从大数组中仅获取前 N 个已排序元素的一种方法是使用部分快速排序,除非需要,否则您不必费心对正确的分区进行排序。这需要将整个数组保存在内存中,这在您的情况下可能是不切实际的。
您可以将输入分成中等大小的块,应用一些巧妙的算法来获取每个块的前 N 行,将这些块连接在一起,然后将相同的算法应用于结果。根据块的大小,sort ... | head
可能足够聪明。split -l ...
将用于执行此操作的 shell 脚本组合在一起应该不难。
(根据需要插入更多的挥手。)
免责声明:我只是在一个比你正在使用的文件(大约 170 万行)小得多的文件上尝试了这个,而且我的方法比sort ... | head
.