我有一个文本文件,如下所示:
blah blah
foo1 bar1
foo1 bar2
foo1 bar3
foo2 bar4
foo2 bar5
blah blah
现在我想在'foo bar'
和'foo1 bar3'
之间插入'foo2 bar4'
。
我就这样做了:
import shutil
txt = '1.txt'
tmptxt = '1.txt.tmp'
with open(tmptxt, 'w') as outfile:
with open(txt, 'r') as infile:
flag = 0
for line in infile:
if not line.startswith('foo1') and flag == 0:
outfile.write(line)
continue
if line.startswith('foo1') and flag == 0:
flag = 1
outfile.write(line)
continue
if line.startswith('foo1') and flag == 1:
outfile.write(line)
continue
if not line.startswith('foo1') and flag == 1:
outfile.write('foo bar\n')
outfile.write(line)
flag = 2
continue
if not line.startswith('foo1') and flag == 2:
outfile.write(line)
continue
shutil.move(tmptxt, txt)
这适合我,但看起来很难看。
答案 0 :(得分:57)
在Python中对文件进行“伪就位”更改的最佳方法是使用标准库中的fileinput
模块:
import fileinput
processing_foo1s = False
for line in fileinput.input('1.txt', inplace=1):
if line.startswith('foo1'):
processing_foo1s = True
else:
if processing_foo1s:
print 'foo bar'
processing_foo1s = False
print line,
如果要保留旧版本,也可以指定备份扩展名,但这与代码的工作方式相同 - 使用.bak
作为备份扩展名,但一旦更改了,也会将其删除顺利完成。
除了使用正确的标准库模块之外,这段代码使用更简单的逻辑:在每行以"foo bar"
开头的行之后插入foo1
行,你需要一个布尔值(我在里面是这样的)是否运行?)并且可以根据当前行是否以这种方式开始无条件地设置有问题的bool。如果你想要的精确逻辑与这个逻辑略有不同(这是我从你的代码中推断出来的),那么相应地调整这个代码应该不难。
答案 1 :(得分:12)
改编Alex Martelli的例子:
import fileinput
for line in fileinput.input('1.txt', inplace=1):
print line,
if line.startswith('foo1 bar3'):
print 'foo bar'
答案 2 :(得分:9)
回想一下迭代器是一流的对象。它可用于多个 for 语句。
这是一种处理这种方法的方法,没有很多复杂的if语句和标志。
with open(tmptxt, 'w') as outfile:
with open(txt, 'r') as infile:
rowIter= iter(infile)
for row in rowIter:
if row.startswith('foo2'): # Start of next section
break
print row.rstrip(), repr(row)
print "foo bar"
print row
for row in rowIter:
print row.rstrip()