3

次の3つのステップを達成するためのより良い解決策を見つけたいと思います。

  1. 特定の行の文字列を読み取る
  2. 文字列を更新
  3. 更新された文字列を書き戻します

以下は動作する私のコードですが、より良い(単純な)解決策はありますか?

new='99999'

f=open('C:/Users/th/Dropbox/com/MS1Ctt-P-temp.INP','r+')
lines=f.readlines()
#the row number we want to update is given, so just load the content
x = lines[95]
print(x)
f.close()


#replace
f1=open('C:/Users/th/Dropbox/com/MS1Ctt-P-temp.INP')
con = f1.read()
print con
con1 = con.replace(x[2:8],new) #only certain columns in this row needs to be updated
print con1
f1.close()


#write
f2 = open('C:/Users/th/Dropbox/com/MS1Ctt-P-temp.INP', 'w')
f2.write(con1)
f2.close()

ありがとう!更新:今回はjtmouliaからアイデアを得るのが簡単になります

def replace_line(file_name, line_num, col_s, col_e, text):
    lines = open(file_name, 'r').readlines()
    temp=lines[line_num]
    temp = temp.replace(temp[col_s:col_e],text)
    lines[line_num]=temp
    out = open(file_name, 'w')
    out.writelines(lines)
    out.close()
4

4 に答える 4

3

表形式であっても、テキスト データの問題は、バイト オフセットが予測できないことです。たとえば、数値を文字列で表す場合は 1 桁あたり 1 バイトですが、2 進数 (2 の補数など) を使用する場合は、小さい整数と大きい整数のどちらにも常に 4 バイトまたは 8 バイトが必要です。

それにもかかわらず、テキスト形式がファイルのサイズを変更せずにバイトを置き換えるだけでうまくいくほど厳密である場合は、標準mmapモジュールを使用してみてください。これにより、ファイルを変更可能なバイト文字列として扱い、その一部をその場で変更して、カーネルにファイルの保存を任せることができます。

それ以外の場合は、他の回答の方が問題に適しています。

于 2012-05-23T00:06:40.857 に答える
1

まず第一に、毎回ファイルを再度開いて読み取る必要はありません。このr+モードにより、指定されたファイルの読み取りと書き込みが可能になります。

おそらく次のようなもの

with open('C:/Users/th/Dropbox/com/MS1Ctt-P-temp.INP', 'r+') as f:
    lines = f.readlines()
    #... Perform whatever replacement you'd like on lines
    f.seek(0)
    f.writelines(lines)

また、Pythonでテキストファイルの特定の行を編集する

于 2012-05-22T23:38:55.253 に答える
0

(Webmin のカスタマイズのために) 似たようなことをしなければならなかったときは、Webmin フレームワークが使用していたものなので、完全に PERL で行いましたが、非常に簡単であることがわかりました。Pythonにも同等のものがあると思います(ただし、確かなことはわかりません)。最初に、ファイル全体を一度にメモリに読み込みます (これを行う PERL の方法は、おそらく "slurp" と呼ばれます)。(1 行だけではなく、ファイル全体をメモリに保持するというこの考えは、以前はほとんど意味がありませんでした {または不可能でした}。しかし、最近では RAM が非常に大きいため、唯一の方法です。)split演算子を使用してファイルを行に分割し、各行を巨大な配列の異なる要素に配置します。次に、目的の行番号を配列のインデックスとして使用できます (配列インデックスは通常 0 から始まることに注意してください)。最後に、「正規表現」処理を使用して行のテキストを変更します。次に、別の行を変更し、別の行を変更します (または同じ行に別の変更を加えます)。すべて完了したら、 を使用joinして、配列内のすべての行を 1 つの巨大な文字列にまとめます。次に、変更されたファイル全体を書き出します。

私は完全なコードを手近に持っていませんが、ここにいくつかの PERL コードのおおよその断片を示します。

our @filelines = ();
our $lineno = 43;
our $oldstring = 'foobar';
our $newstring = 'fee fie fo fum';
$filelines[$lineno-1] =~ s/$oldstring/$newstring/ig; 
# "ig" modifiers for case-insensitivity and possible multiple occurences in the line
# use different modifiers at the end of the s/// construct as needed
于 2012-05-22T23:49:31.653 に答える
-1
FILENAME = 'C:/Users/th/Dropbox/com/MS1Ctt-P-temp.INP'
lines = list(open(FILENAME))
lines[95][2:8] = '99999'
open(FILENAME, 'w').write(''.join(lines))
于 2012-05-22T23:35:51.180 に答える