
私巨大な次の行を含むファイル(〜70 GB):
$ 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
2つの新しいファイルが作成され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