使用stdout和fileinput将Python写入文件

6
我有如下代码,它通过进行正则表达式替换来修改test.tex文件中的每一行。
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),

唯一的问题是我只想应用替换到文件中的某些行,而且没有办法定义一个模式来选择正确的行。因此,我想显示每行并在命令行提示用户,询问是否在当前行进行替换。如果用户输入"y",则进行替换。如果用户什么也不输入,则进行替换。
问题在于,通过使用inplace=1代码,我有效地将stdout重定向到了打开的文件。因此,没有办法显示输出(例如询问是否进行替换)到不被发送到文件的命令行上。
有什么好的想法吗?

fileinput 不是适合这个任务的正确工具。只需使用标准的读取-修改-写入模式即可。 - Eli Bendersky
@EliBendersky,你能给我指一个做这件事情的例子吗?抱歉,我在Python方面非常新手。 - synaptik
有什么想法吗?是的。不要使用fileinput inplace。在文件上进行常规的open()操作,获取用户输入,写入临时文件,完成后将临时文件移动以替换原始文件。 - James Thiele
2个回答

4
文件输入模块实际上是用于处理多个输入文件的。您可以使用常规的open()函数代替它。
像这样的代码应该可以工作。
通过读取文件,然后使用seek()重置指针,我们可以覆盖文件而不是将其附加到末尾,从而就地编辑文件。
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


2
当然,如果你有一个太大无法加载到内存的巨大文件,那么你可以一次读取一行,并将其写入临时文件中。 - user391538

0

根据大家提供的帮助,这是我最终采用的方案:

#!/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)

非常感谢!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接