Pythonでテキストブロックを解析する効率的な方法はありますか?

Pythonでテキストブロックを解析する効率的な方法はありますか?

巨大な次の行を含むファイル(〜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.txt2つの新しいファイルが作成され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の形式です。ii=6i=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

おすすめ記事