2009-08-25 53 views
30

的指定位置我有一个文本文件,它看起来像这样:插入线在文本文件

blah blah 
foo1 bar1 
foo1 bar2 
foo1 bar3 
foo2 bar4 
foo2 bar5 
blah blah 

现在我想'foo1 bar3''foo2 bar4'之间插入'foo bar'

这是我做的:

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) 

这对我的作品,但看起来比较难看。

回答

55

使“伪就地”更改为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作为备份扩展,但也会在更改成功完成后将其删除。

除了使用正确的标准库模块,该代码使用简单的逻辑:插入开始foo1线的每一次运行后"foo bar"线,一个布尔值是所有你需要(我是这样的运行内部或不是?),并所讨论的布尔值可以根据当前行是否以这种方式开始而无条件设置。如果你期望的精确逻辑与这个(这是我从你的代码中推导出来的)稍有不同,那么相应地调整这个代码应该不难。

9

回想一下,迭代器是第一类对象。它可用于多个陈述。

这里有一个方法来处理这个没有很多复杂的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() 
+0

感谢您的完全不同的方法。 – 2009-08-25 14:40:59

13

适应亚历克斯·马尔泰利的例子:

import fileinput 
for line in fileinput.input('1.txt', inplace=1): 
print line, 
if line.startswith('foo1 bar3'): 
    print 'foo bar'