在每行上前两个字符拆分一个大的平面文件

时间:2014-11-10 21:57:02

标签: python regex bash awk sed

我有一个大文件~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
...

任何建议都将不胜感激。

5 个答案:

答案 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)