我使用sort | uniq -c | sort -n
多年,但今天它失败了,因为我的输入文件是10 GB而我的/tmp
是1 GB宽:
sort: write failed: /tmp/sortmIGbL: No space left on device
因此,我正在寻找日常使用的有效替代方案:
awk
,但没有排序的关联数组
perl
似乎是一个不错的选择,但10-years-old solution from perlmonks.org似乎不起作用
no warnings;
$^W=0;
open my $in, $ARGV[0] or die "Couldn't open $ARGV[0]:$!";
my ($buffer, %h) = ''; keys %h = 1024*500;
while (sysread($in, $buffer, 16384, length $buffer)) {
$h{$1}++ while $buffer =~ m[^(?:.+?\|){9}([^|]+)\|]mg;
$buffer = substr($buffer, rindex($buffer, "\n"));
}
print scalar keys %h;
sort | uniq -c | sort -nr | head
相同的结果?awk
/ perl
/ ...)a
BB
ccccc
dddddddd
a
BB
a
3 a
2 BB
1 dddddddd
1 ccccc
答案 0 :(得分:5)
您的命令链中的第一个sort
是使用所有资源的命令。通过获取首先的唯一行,然后排序:
perl -ne '
$count{$_}++;
END {
print "$count{$_} $_" for sort {
$count{$b} <=> $count{$a} || $b cmp $a
} keys %count
}
' input.txt
你有66,000个7字节的唯一行,因此对于每个scalars = 3,696,000字节的密钥,散列键占用的内存将是66,000 * 56字节。这不包括哈希的计数和开销,但毫无疑问,这种方法很容易做到。
答案 1 :(得分:3)
排序不是顺序操作,例如你不能只读取10条记录,对它们进行排序,转发它们,然后再记录10条记录。因此,如果您想要对10GB数据进行排序
答案 2 :(得分:3)
使用GNU awk进行排序关联数组:
$ gawk '
BEGIN{ PROCINFO["sorted_in"] = "@val_num_desc" }
{ a[$0]++ }
END { for (i in a) print a[i], i }
' file
3 a
2 BB
1 dddddddd
1 ccccc
不知道它是否能够有效地为您的大型数据集工作,只是在他的问题下方的OPs评论中显示一个awk排序的关联数组。