Вставка строки в заданное положение текстового файла
У меня есть текстовый файл, который выглядит так:
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)
Это работает для меня, но выглядит довольно уродливо.
Ответы
Ответ 1
Лучший способ сделать "псевдо-inplace" изменения в файле на 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 может быть установлен безоговорочно только на основе того, начинается ли эта строка или нет. Если точная логика, которую вы желаете, немного отличается от этой (это то, что я вывел из вашего кода), это не должно быть трудно подстроить этот код соответственно.
Ответ 2
Адаптация примера Алекса Мартелли:
import fileinput
for line in fileinput.input('1.txt', inplace=1):
print line,
if line.startswith('foo1 bar3'):
print 'foo bar'
Ответ 3
Напомним, что итератор является первоклассным объектом. Он может использоваться в нескольких операциях для.
Вот способ справиться с этим без множества сложных выглядящих 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()