您的位置:首页 > 运维架构 > Shell

Shell 排序大文件

2016-01-09 19:00 411 查看
题目:一句 Shell 脚本,使用 2G 内存,排序一个 10G 的文件。

准备工作

首先,我们用 Python 脚本计算一个 10G 的文件最大的整数是多少(因为硬盘的原因就以 10M 为例),10M 得到的结果是 1449607。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# First approache
total = 1024*1024*10
total -= 2
count = 0
for i in range(1, 100000):
size = (10**i-10**(i-1))*(i+1)
if total >= size:
total -= size
count = i
else:
break
print (total/(count+2)) - 1 + 10**count
print "Remain Bytes: ", total%(count+2)

# Second approache
# 只做小数据时验证使用
total = 1024*1024*10
for i in range(0, 10000000):
total -= len(str(i)) + 1
if total < 0:
print i-1
print "Remain Bytes: ", total+ len(str(i)) + 1
break

然后,调用 seq 和 shuf(在 OS X 下可以先执行 brew
install coreutils 安装软件包,然后使用 shuf)命令生成打乱的文件。

1
2

seq -f '%0.f' 0 1449607 > old_dat
gshuf old_data -o old_data2

如果不放心自己生成文件的大小,可以用 Hex Field 查看一下:



具体 Shell 的编写

由于 sort 命令会把所有传递给它的数字存在内存里排序,所以把所有的内容分为几部分进行排序可以减少 sort 所占用的内存。虽然多扫了几次文件,但是内存可以少占用很多。由于我们最大的数字就是 1449607,还不到 2M 个数字,所以每次处理 1M 的话,分两次就搞定了。

1
23

for i in `seq 0 1`;
do awk 'BEGIN{i='$i'}{if($1>=1024*i && $1<1024*(i+1))print $0}' old_data2 | sort -g >> new_data;
done;

最后,比较一下排序出的文件与最初的文件是否相同,相同就说明我们的命令写对了。

1

diff old_data new_data

最后

这还只是一个很粗浅的方法,但是摸索的过程中学到了很多 Shell 的知识。后续可能会找个工具测一下 sort 命令的执行效率,进而给出更准确的答案。

相关链接

十道海量数据处理面试题与十个方法大总结 - 结构之法 算法之道 - 博客频道 - CSDN.NET

lodevil/Lo-runner
- EOF -
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: