se você está bem com o comando awk, então tente isso ...
awk 'NF==2{filename="v0"$2".txt"}{print > filename}' mybigfile.txt
Eu tenho um arquivo enorme (~ 70GB) com linhas parecidas com esta:
$ 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
Eu quero dividir meu enorme arquivo em vários arquivos menos enormes organizando cada bloco pelo último caractere em seu cabeçalho. Portanto, executar $ python magic.py mybigfile.txt
deve produzir dois novos arquivos v07.txt
e 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
Os cabeçalhos de cada bloco são todos do formato 5 i
com i
variando de i=6
a i=22
.
Esse tipo de coisa é factível? A única linguagem que eu estou confortável o suficiente para começar é python, então eu prefiro uma solução python, se possível.
Aqui está a minha solução:
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()
Minhas soluções percorre cada bloco e repetidamente abre e fecha os arquivos de saída. Eu suspeito que isso pode ser muito mais eficiente, mas não sei como melhorar meu código.
Tags python large-files