I'm fairly new to python and I am trying to write a script which reads x lines from a file and then writes that to new file. I would like it to iterate over all the subsequent lines writing to separate new files each time. The first 7 lines need to go in every new file.
Example format of the file to read is below:
Line 1: Data for EVERY new file
...
...
Line 8: Data to write to file one
...
...
Line 49: Data to write to file two
...
...
I have tried using itertools.islice but am not sure how to loop it for subsequent lines as well as into new files each time.
Sample code:
import os
from itertools import islice
#os.chdir("directory where XDATCAR is")
#ignore if .py is in the same directory
with open('XDATCAR' , 'r') as f:
for line in islice(f, 2, 7,):
print(line, end='')
with open('POSCAR','w') as n:
n.writelines()
I get the error:
ValueError: I/O operation on closed file.
Which I understand to be because 'with' closes the file after execution.
What I would like as output for each new file:
File 1:
First 7 lines of read file
lines 8 to 48
File 2:
First 7 lines of read file
lines 49 to 89
...
etc
CodePudding user response:
I did this by saving the contents of "XDATCAR" into a list and iterating over it.
# read the lines
f=open("XDATCAR")
lines=f.readlines()
f.close()
file_number=0 # counter for the files
line_counter=0 # keeps track of the number of lines written in the file so far
for i in range(8,len(lines)):
if line_counter==0: # we started writing to a file
f=open("file_" str(file_number) ".txt","w") # open file
for j in range(7):# write the first seven lines
f.write(lines[j])
f.write(lines[i])# write one line
line_counter =1 # increment line counter
if line_counter == 40:
f.close()
file_number =1 # start writing to a new file
line_counter=0
if f.closed == False: # the file was not closed properly in the for loop
f.close()
CodePudding user response:
This sounds like a job for more_itertools.chunked:
This code
- reads in the header lines
- uses the
ichunkedgenerator to make large chunks
import more_itertools
def write_chunk(i, header, chunk):
output_filename = f"file_{i}.txt"
with open(output_filename, "w") as w:
w.writelines(header)
w.writelines(chunk)
def make_chunks(lines):
header = tuple(itertools.islice(lines, 0, 7))
body = lines
chunks = more_itertools.chunked(body, 6*7)
for i, chunk in enumerate(chunks):
write_chunk(i, header, chunk)
with open("XATCAR") as lines:
make_chunks(lines)
CodePudding user response:
Let us write down what you want to do:
- read 7 lines from the input file. Those lines should be saved because they will be used for all output file
- read 41 lines from the input file, and write them to the output file after the 7 initial lines
- iterate step 2 until the input file is exhausted
Code could be:
...
with open('XDATCAR' , 'r') as f:
# read 7 lines into a list:
header = [next(f) for _ in range(7)]
filenum = 0
while True:
# output file
with open(f'POSTCAR{filenum}', 'w') as out:
for line in header: # copy 7 initial lines
out.write(line)
for i in range(41): # try to copy 41 lines
try:
out.write(next(f))
except StopIteration:
break
filenum = 1
# remove last file if no line was used
if i == 0:
os.remove(f'POSTCAR{filenum}')
