我有一个35GB的文件,其中包含各种字符串示例:
test1
test2
test1
test34!
test56
test56
test896&
test1
test4
etc
...
有数十亿行。
我想对它们进行排序并计算出现的次数,但是花了2天的时间才完成。
这是我在bash中使用的:
cat file.txt | sort | uniq -c | sort -nr
有没有更有效的方法?还是有办法查看进度,或者它会加重我的计算机并使其变得更慢?
答案 0 :(得分:2)
如果有很多重复项,即如果唯一的行适合您的可用内存,则可以对行进行计数并使用GNU awk进行排序:
$ awk '{
a[$0]++ # hash the lines and count
}
END { # after counting the lines
PROCINFO["sorted_in"]="@val_num_desc" # used for traverse order
for(i in a)
print a[i],i
}' file
输出示例数据:
3 test1
2 test56
1 test34!
1 test2
1 test4
1 etc
1 test896&
1 ...
相关文档:https://www.gnu.org/software/gawk/manual/html_node/Controlling-Scanning.html
更新由于内存不足(请参见注释),请在该行的0-2个开头字符处分割文件。分布将不均匀:
$ awk '{
ch=substr($0,match($0,/^.{0,2}/),RLENGTH) # 0-2 first chars
if(!(ch in a)) # if not found in hash
a[ch]=++i # hash it and give a unique number
filename=a[ch]".txt" # which is used as filename
print >> filename # append to filename
close(filename) # close so you wont run out of fds
}' file
输出测试数据:
$ ls -l ?.txt
-rw-rw-r-- 1 james james 61 May 13 14:18 1.txt
-rw-rw-r-- 1 james james 4 May 13 14:18 2.txt
-rw-rw-r-- 1 james james 4 May 13 14:18 3.txt
$ cat 3.txt
...
在50秒内 300 MB和150万行。如果我删除了close()
,则只花了5秒钟,但是您可能会用完文件描述符。我想你可以增加这个数额。