我有一个大文件~10 GB,用逗号分隔。每行以2个字符的代码开头,该代码告诉它是什么类型的行,因为每行是不同类型的事件。目前我将文件读入R,然后使用正则表达式将其拆分为基于代码的不同部分,然后将生成的对象写入平面文件。
我很好奇是否有更直接的方法(读取一行,确定行类型并将行附加到相应的平面文件(总共将有7个)),在Python中,bash ,sed / awk等。
数据如下所示:
01,tim@bigcompany.com,20140101120000,campaign1
02,201420140101123000,123321,Xjq12090,TX
02,201420140101123000,123321,Xjq12090,AK
...
任何建议都将不胜感激。
答案 0 :(得分:7)
使用awk你可以这样做:
awk -F, '{fn=$1 ".txt"; print > fn}' file
如果要通过最后关闭所有文件句柄来保持清洁,请使用此awk
:
awk -F, '!($1 in files){files[$1]=$1 ".txt"} {print > files[$1]}
END {for (f in files) close(files[$f])}' file
答案 1 :(得分:2)
如果您不关心性能,或信任您的操作系统/文件系统/驱动器的磁盘缓存:
with open('hugedata.txt') as infile:
for line in infile:
with open(line[:2] + '.txt', 'a') as outfile:
outfile.write(line)
然而,不断重新打开和重新关闭(并因此刷新)文件意味着你永远不会得到缓冲的好处,并且只有这么多的磁盘缓存才能弥补这一点,因此,您可能要考虑预先打开所有文件。由于只有7个,这很容易:
files = { format(i, '{:02}'): open(format(i, '{:02}.txt'), 'w') for i in range(1, 8)}
try:
with open('hugedata.txt') as infile:
for line in infile:
files[line[:2]].write(line)
finally:
for file in files:
file.close()
或者,更强大:
files = collections.defaultdict(lambda s: open(s+'.txt', 'w'))
try:
with open('hugedata.txt') as infile:
for line in infile:
files[line[:2]].write(line)
finally:
for file in files:
file.close()
(你可以写一个自动关闭的with
语句,但它在不同的Python版本中会有所不同;这有点笨拙,但适用于从2.4到3.5的所有内容,可能超越,既然你没有告诉我们你的平台或Python版本,它似乎更安全。)
答案 2 :(得分:1)
Python中的这类内容如何:
for line in file('hugedata.txt'):
fh = file(line[:2] + '.txt', 'a')
fh.write(line)
答案 3 :(得分:1)
我会做这样的事情:
grep '^01' your-10gb-file > 01.csv
然后你可以将它包装在foreach(对于tcsh)中,如下所示:
foreach n ( `seq -f '%02g' 7` )
grep '^$n' your-10gb-file > $n.csv
end
答案 4 :(得分:1)
from itertools import groupby
with open("largefile.txt") as f:
for k,v in groupby(f,lambda x: x[:2]):
with open("{}.txt".format(k),"w") as f1:
f1.writelines(v)