0

タスク

毎回新しい.s2kファイルをSap2000プログラムにインポートしてSAP2000プログラムを実行するプログラムをPythonで作成しています。その後、データをエクスポートすることにより、前回の実行結果から新しいファイルが生成されます。

このファイルは、任意の単語と数字を含む約1,500行です。(より良い理解のために、これを参照してください:http: //pastebin.com/8ptYacJz、これは私が扱っているファイルです。)

ファイル内の1つの番号を置き換える必要があります。その番号は800行目の真ん中のどこかにあります。

質問

1つの番号を置き換えるために、ファイルの800行目の中央に移動する効率的な方法を知っている人はいますか?

私が試したこと

同じ番号のインスタンスが複数存在する可能性があるため、正規表現は機能しませんでした。

そこで、ファイルをテンプレート化し、変更する番号をテンプレートパラメータとして毎回新しいファイルを作成するという解決策を思いつきました。

この解決策は機能しますが、その人は、ファイルポインタを800行目まで下に移動し、次に行の中央に移動して番号を置き換えることができると主張しています。

これは、ファイルバッファを1行に移動し、シークしようとしたときに最初に戻るという問題に対して私が持っている唯一のコードです。

import sys
import os
#open file
f = open("output.$2k")
#this will go to line 883 in text file
count = 0;
while count < 883:
    line = f.readline()
    count = count+1
#this would seek over to middle of file DOESN'T WORK
f.seek(0,0)
line = f.readline()
print(line)
f.close()
4

4 に答える 4

1

OK、私はプロのプログラマーではありませんが、私の(ばかげた)アプローチは次のようになります。常に800行目である場合は、行番号を追跡しながらファイルを1行ずつ読み取ります。次に、新しいファイルに直接書き込みます。行800を読み取り、変更し、書き込みます。その後、残りを書きます。ばかげていてエレガントではありませんが、うまくいくはずです-おそらく私がやっていることを見逃さない限り。そして、私のわずかな評判があります:D

于 2012-07-16T19:01:32.540 に答える
1

はいといいえ。検討:

f=open('output.$2k','r+')
f.seek(300)
f.write('\n')
f.close()

このスクリプトは、ASCIIファイルの300番目の文字を改行に変更するだけです。ここで注意が必要なのは、改行に到達するまで、ASCIIファイルの行の長さを読み取る以外に知る方法がないことです。したがって、ファイル内の800行目の中央に特定の文字を配置することは簡単ではありません。ただし、(ファイルの書き込み方法により)行の長さを保証できれば、問題なく位置を計算できます。1また、ここでの置き換えは機能しないことに注意して100ください。1文字を1文字に置き換える必要があります。

$そして、世界中の他のすべての*NIXユーザーのためだけに...ファイル名を入力しないでください。それはただの悪夢です...

于 2012-07-16T18:53:14.733 に答える
0

いいえ。その行を読み取り、操作してから、以前に書き込み用に開いた(そして他の行を変更せずに書き込んでいる)新しいファイルに書き込みます。

于 2012-07-16T18:53:20.133 に答える
0

まず最初に:

#this would seek over to middle of file DOESN'T WORK
f.seek(0,0)

本当じゃない。これはファイルの先頭を探します。


あなたの実際の質問に:

1つの番号を置き換えるために、ファイルの800行目の中央に移動する効率的な方法を知っている人はいますか?

一般的に、いいえ。ファイルを書き直す必要があります。たとえば、次のようになります。

# open the file in read-and-update mode
with open("file", 'r+') as f:
  # read all lines
  lines = f.readlines()

  # update 800'th line 
  my_line = lines[799].split()
  my_line[5] = "%s" % my_number # TODO: put in index of number and updated number 
  lines[799] = " ".join(my_line)

  # truncate and rewrite file
  f.truncate(0)
  f.writelines(lines)

ファイル内の数値の開始位置が予測可能であり(たとえばnumber_starting_pos = 1234、ファイルの先頭から)、文字列表現のサイズも予測可能である場合(たとえば20)、これを行うことができます。次に、番号を書き直して、前のエントリのコンテンツを上書きするために、パディングを空白で埋めてください。これに似ています:

with open("file", 'r+') as f:
  # seek to the number starting position
  f.seek(number_starting_pos, 0)

  # update number field, assuming width (20), arbitrary space-padding allowed
  my_number_string = "%19s " % my_number
  # make sure the string is indeed exactly of the specific size (it may be longer)
  assert len(my_number_string) == 20, "file writing would fail! aborting!"
  f.write(my_number_string)

これを機能させるには、SAP-thingyのドキュメントを調べて、空白が実際に重要でないかどうかを確認する必要があります。


ただし、どちらのアプローチも多くの仮定に基づいています。ユースケースによっては、コードが簡単に壊れることがあります。たとえば、行が挿入されたり、数字フィールドの前に文字が挿入されたりした場合などです。

于 2012-07-16T21:41:58.413 に答える