Вставка строки в указанной позиции текстового файла - PullRequest
31 голосов
/ 25 августа 2009

У меня есть текстовый файл, который выглядит так:

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 ]

57 голосов
/ 25 августа 2009

Лучший способ сделать "псевдо-замену" изменений в файле в 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 может быть установлено безоговорочно только на основании того, начинается ли текущая строка таким образом или нет. Если точная логика, которую вы хотите, немного отличается от этой (что я и вывел из вашего кода), то нетрудно настроить этот код соответствующим образом.

12 голосов
/ 08 июня 2011

Адаптируя пример Алекса Мартелли:

import fileinput
for line in fileinput.input('1.txt', inplace=1):
 print line,
 if line.startswith('foo1 bar3'):
     print 'foo bar'
9 голосов
/ 25 августа 2009

Напомним, что итератор является первоклассным объектом. Может использоваться в нескольких для операторов.

Вот способ справиться с этим без большого количества сложных операторов 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...