Reputation: 9499
I have the following code, which modifies each line of the file test.tex by making a regular expression substitution.
import re
import fileinput
regex=re.compile(r'^([^&]*)(&)([^&]*)(&)([^&]*)')
for line in fileinput.input('test.tex',inplace=1):
print regex.sub(r'\3\2\1\4\5',line),
The only problem is that I only want the substitution to apply to certain lines in the file, and there's no way to define a pattern to select the correct lines. So, I want to display each line and prompt the user at the command line, asking whether to make the substitution at the current line. If the user enters "y", the substitution is made. If the user simply enters nothing, the substitution is not made.
The problem, of course, is that by using the code inplace=1
I've effectively redirected stdout to the opened file. So there's no way to show output (e.g. asking whether to make the substitution) to the command line that doesn't get sent to the file.
Any ideas?
Upvotes: 6
Views: 8081
Reputation: 9499
Based on the help everyone provided, here's what I ended up going with:
#!/usr/bin/python
import re
import sys
import os
# regular expression
regex = re.compile(r'^([^&]*)(&)([^&]*)(&)([^&]*)')
# name of input and output files
if len(sys.argv)==1:
print 'No file specified. Exiting.'
sys.exit()
ifilename = sys.argv[1]
ofilename = ifilename+'.MODIFIED'
# read input file
ifile = open(ifilename)
lines = ifile.readlines()
ofile = open(ofilename,'w')
# prompt to make substitutions wherever a regex match occurs
for line in lines:
match = regex.search(line)
if match is not None:
print ''
print '***CANDIDATE FOR SUBSTITUTION***'
print '--: '+line,
print '++: '+regex.sub(r'\3\2\1\4\5',line),
print '********************************'
input = raw_input('Make subsitution (enter y for yes)? ')
if input == 'y':
ofile.write(regex.sub(r'\3\2\1\4\5',line))
else:
ofile.write(line)
else:
ofile.write(line)
# replace original file with modified file
os.remove(ifilename)
os.rename(ofilename, ifilename)
Thanks a lot!
Upvotes: 0
Reputation:
The file input module is really for dealing with more than one input file. You can use the regular open() function instead.
Something like this should work.
By reading the file then resetting the pointer with seek(), we can override the file instead of appending to the end, and so edit the file in-place
import re
regex = re.compile(r'^([^&]*)(&)([^&]*)(&)([^&]*)')
with open('test.tex', 'r+') as f:
old = f.readlines() # Pull the file contents to a list
f.seek(0) # Jump to start, so we overwrite instead of appending
for line in old:
s = raw_input(line)
if s == 'y':
f.write(regex.sub(r'\3\2\1\4\5',line))
else:
f.write(line)
http://docs.python.org/tutorial/inputoutput.html
Upvotes: 4