web-dev-qa-db-ja.com

テキストファイルの指定した位置に行を挿入する

次のようなテキストファイルがあります。

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)

これは私には有効ですが、かなりratherいように見えます。

31
Wang Dingwei

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行を挿入するために、必要なのはブール値だけですそして、現在の行がそのように始まるかどうかに基づいて、問題のブールを無条件に設定できます。あなたが望む正確なロジックがこれとわずかに異なる場合(これはあなたのコードから推測したものです)、それに応じてこのコードを微調整することは難しくないはずです。

57
Alex Martelli

アレックスマルテッリの例の適応:

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

イテレータはファーストクラスのオブジェクトであることを思い出してください。複数の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()
9
S.Lott