在文本文件的指定位置插入行

时间:2009-08-25 03:27:24

标签: python text insert

我有一个文本文件,如下所示:

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)

这适合我,但看起来很难看。

3 个答案:

答案 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()