テキスト ファイルの内容をループし、いくつかの行を検索して置換し、その結果をファイルに書き戻したいと考えています。最初にファイル全体をメモリにロードしてから書き戻すこともできますが、おそらくこれは最善の方法ではありません。
次のコード内でこれを行う最良の方法は何ですか?
f = open(file)
for line in f:
if line.contains('foo'):
newline = line.replace('foo', 'bar')
# how to write this newline back to the file
ベストアンサー1
最も短い方法はおそらくファイル入力モジュールたとえば、次のコードはファイルに行番号をその場で追加します。
import fileinput
for line in fileinput.input("test.txt", inplace=True):
print('{} {}'.format(fileinput.filelineno(), line), end='') # for Python 3
# print "%d: %s" % (fileinput.filelineno(), line), # for Python 2
ここで起こることは次のとおりです:
- 元のファイルはバックアップファイルに移動されます
- 標準出力はループ内の元のファイルにリダイレクトされます
- したがって、すべての
print
ステートメントは元のファイルに書き戻されます
fileinput
にはさらに多くの機能があります。たとえば、 内のすべてのファイルに対してsys.args[1:]
、明示的に反復処理することなく自動的に操作することができます。Python 3.2 以降では、ステートメントで使用するための便利なコンテキスト マネージャーも提供されますwith
。
使い捨てのスクリプトには最適ですがfileinput
、実際のコードで使用するのは慎重にした方が良いでしょう。なぜなら、読みやすくも使い慣れてもいないからです。実際の (本番) コードでは、プロセスを明示的にしてコードを読みやすくするために、ほんの数行のコードを追加する価値はあります。
次の 2 つのオプションがあります。
- ファイルはそれほど大きくないので、そのままメモリにすべて読み込んでください。その後、ファイルを閉じて、書き込みモードで再度開き、変更した内容を書き戻します。
- ファイルはメモリに保存するには大きすぎます。一時ファイルに移動してそれを開き、行ごとに読み取り、元のファイルに書き戻すことができます。この場合、2 倍のストレージが必要になることに注意してください。