我有一个巨大的文件(~70GB),其行如下所示:
$ cat mybigfile.txt
5 7
1 1 0 -2 0 0 2
0 4 0 -4 0 0 4
0 0 1 -1 0 0 0
0 0 0 0 1 0 -1
0 0 0 0 0 1 -1
5 8
-1 -1 -1 -1 -1 1 1 1
0 0 2 0 0 0 -1 -1
3 3 3 -1 -1 -1 -1 -1
-1 -1 -1 0 2 0 0 0
-1 1 -1 0 0 0 1 0
5 7
1 1 0 -2 0 0 5
0 2 0 -2 0 0 2
0 0 1 -1 0 0 0
0 0 0 0 1 0 -4
0 0 0 0 0 1 -4
5 7
1 1 0 -2 0 1 -1
0 2 0 -2 0 0 4
0 0 1 -1 0 0 0
0 0 0 0 1 0 -2
0 0 0 0 0 2 -4
我想通过按文件头中的最后一个字符组织每个块,将我的大文件分成几个较小的文件。因此,运行$ python magic.py mybigfile.txt
应该会产生两个新文件v07.txt
并且v08.txt
$ cat v07.txt
5 7
1 1 0 -2 0 0 2
0 4 0 -4 0 0 4
0 0 1 -1 0 0 0
0 0 0 0 1 0 -1
0 0 0 0 0 1 -1
5 7
1 1 0 -2 0 0 5
0 2 0 -2 0 0 2
0 0 1 -1 0 0 0
0 0 0 0 1 0 -4
0 0 0 0 0 1 -4
5 7
1 1 0 -2 0 1 -1
0 2 0 -2 0 0 4
0 0 1 -1 0 0 0
0 0 0 0 1 0 -2
0 0 0 0 0 2 -4
$ cat v08.txt
5 8
-1 -1 -1 -1 -1 1 1 1
0 0 2 0 0 0 -1 -1
3 3 3 -1 -1 -1 -1 -1
-1 -1 -1 0 2 0 0 0
-1 1 -1 0 0 0 1 0
每个块的头部都是5 i
从i
到i=6
的形式i=22
。
这种事情可行吗?我唯一熟悉的入门语言是 python,所以如果可能的话,我更喜欢 python 解决方案。
这是我的解决方案:
from string import whitespace
import sys
class PolyBlock(object):
def __init__(self, lines):
self.lines = lines
def nvertices(self):
return self.lines[0].split()[-1]
def outname(self):
return 'v' + self.nvertices().zfill(2) + '.txt'
def writelines(self):
with open(self.outname(), 'a') as f:
for line in self.lines:
f.write(line)
def __repr__(self):
return ''.join(self.lines)
def genblocks():
with open('5d.txt', 'r') as f:
block = [next(f)]
for line in f:
if line[0] in whitespace:
block.append(line)
else:
yield PolyBlock(block)
block = [line]
def main():
for block in genblocks():
block.writelines()
sys.stdout.write(block.__repr__())
if __name__ == '__main__':
main()
我的解决方案循环遍历每个块并重复打开和关闭输出文件。我怀疑这会更有效,但我不确定如何改进我的代码。
答案1
如果你对 awk 命令没问题,那么试试这个......
awk 'NF==2{filename="v0"$2".txt"}{print > filename}' mybigfile.txt