Reputation: 47
I have an issue with my code. I am trying to replace a pattern un a file. First I have an error on the number of opening files because I forgot to close my file. But now, I had f.close() into my code and I have the following error:
ValueError: I/O operation on closed file.
Here you may find a part of my code. Someone has an idea of what is wrong ?
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
import shutil
from tempfile import mkstemp
infile = 'test_file.txt'
year = int('2009')
month = int('1')
day = int('10')
#################################################################################
def sed(pattern, replace, source):
"""
Reads a source file and writes the destination file.
In each line, replaces pattern with replace.
Args:
pattern (str): pattern to match (can be re.pattern)
replace (str): replacement str
source (str): input filename
"""
fin = open(source, 'r')
fd, name = mkstemp()
fout = open(name, 'w')
for line in fin:
out = re.sub(pattern, replace, line)
fout.write(out)
fin.close()
fout.close()
shutil.move(name, source)
#################################################################################
def main():
"""
Replace all year-month-days which have a possible wrong pattern
"""
for i in range (6):
for j in range (12):
for k in range (22):
Year = year + i; Month = month + j; Day = day + k
pattern = '%s %s%s' %(Year, Month, Day)
replace = '%s %s %s' %(Year, Month, Day)
sed(pattern, replace, infile)
#################################################################################
if __name__ == "__main__":
main()
###### END
Thank you a lot.
Upvotes: 0
Views: 1851
Reputation: 320
I'm posting this as another answer because, well, it's clearly different.
Since you have an issue with your sed
function opening too many files, I tried writing something that opens files as few times as possible. Moreover, you said that the file you want to edit is pretty big, so I avoided reading it directly into memory.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
input_file = 'test_file.txt'
output_file = 'result_file.txt'
def main():
pattern = r"(\d{4}) (\d{1,2})(\d{2})"
replace = r"\1 \2 \3"
with open(input_file, "r") as inp:
with open(output_file, "w") as oup:
for line in inp:
sub = re.sub(pattern, replace, line)
oup.write(sub)
if __name__ == "__main__":
main()
Upvotes: 2
Reputation: 320
I think the issue is that you incorrectly use your sed
function. You open the file you want to edit inside your main
function, and then it is opened again (and then closed) inside the sed
function.
It looks like your sed
function is supposed to be used on an entire file, not just a line.
If you edit your main
function to something like that, it should work (if not, comment what's wrong):
def main():
"""
Replace all year-month-days which have a possible wrong pattern
"""
occurrences = 999 # arbitray number. If you know the exact number, you may want to edit this.
for i in range (6):
for j in range (12):
for k in range (22):
Year = year + i; Month = month + j; Day = day + k
pattern = '%s %s%s' %(Year, Month, Day)
replace = '%s %s %s' %(Year, Month, Day)
sed(pattern, replace, infile, count=occurrences)
Upvotes: 0