2016-03-31 8 views
0

私は、その一部としてperlスクリプトを実行するpythonスクリプトを持っています。私はsubprocessモジュールを使用してstdoutstderrを実行してキャプチャしています。擬似コードは次のとおりです。Python:ファイルに進行状況バーを書き込む

import subprocess as sp 
import sys 
perl_script='/usr/.../foo.pl' 
p = sp.Popen(perl_script,stdout=sp.PIPE,stderr=sp.PIPE) 
fname='test.log' 
shell_out=True 
text = '' 
with open(fname, 'w') as log: 
    while True: 
     data = p.stdout.read(1) 
     if data == '' and p.poll() != None: 
      break 
     if data != '': 
      if shell_out is True: 
       sys.stdout.write(data) 
       sys.stdout.flush() 
      log.write(data) 
    p.stdout.close() 

データは1文字の文字列のようです。

問題は、このperlスクリプトが上書きするプログレスバーを表示していることです。

[#####.....] 50% 

5%ごとに更新されます。そのため、私が書き込むログファイルは、

[#.........] 5% [##........] 10% [###.......] 15% 

などの行に沿って何かを持つことになります。

ログファイルに前の行を上書きする方法や方法がありますか?それとも、すべてのテキストをキャプチャして変更してログファイルに書き込む唯一の方法ですか?

編集:私が与えた例の単純な性質は、全体の話を伝えないかもしれないと思います。このPerlスクリプトには、複数の進行状況バー(各タスクに1つずつ)があり、ログに記録する追加情報が出力されます。より詳細な例は以下のとおりです。

NOTICE: one or more of things did stuff and you probably want to take note of it 
writing the foo file . . . 
    writing things . . .        [####################] 100% 
    writing stuff . . .        [####################] 100% 
    writing items . . .        [####################] 100% 
done 
creating other files... 
done 

上記の出力は、このperlスクリプトの標準出力の特性と一致する例であり、(私が投稿することはできません)実際の出力は、約100以上であることをことを覚えておいてくださいライン。

最後に、書式設定の助けに感謝します:)

編集#2:私はstdoutとして、ログファイルを作成しようとあきらめてきたが捕獲され、代わりに変数にstdoutを保存して書きますスクリプトが終了した後のログファイル。残っている唯一の問題は、ログファイルが正しく書き込まれるように文字列を適切にフォーマットする方法です。更新された擬似コードは、

import subprocess as sp 
import sys 
tg_post='/usr/.../foo.pl' 
p = sp.Popen(tg_post,stdout=sp.PIPE) 
text = '' 
fname='test.log' 
shell_out=True 
while True: 
    data = p.stdout.read(1) 
    if data == '' and p.poll() != None: 
     break 
    if data != '': 
     if shell_out is True: 
      sys.stdout.write(data) 
      sys.stdout.flush() 
     text += data   
p.stdout.close() 
text = text.split('\r') 
with open(fname, 'w') as log: 
    log.write(text) 

です。現時点では、このコードは各ステータスバーの各パーセンテージに対応する行になります。私は、テキスト内の各インデックス上にループして、#があり、100%ではないインデックスを削除することができますが、もっと頑強なものがあることを期待しています。私がprint text(分割後)の場合、私は画面上で何を望みます。 printをファイルに書き込むことは可能ですが、私はそれを避けたいと思います(私はその方法がもう使用されないと信じています)。

+0

なぜログファイルに行を書きたいのですか? –

+0

@ nathan.meadows - 私のログファイルの行を上書きしないと、〜100行のファイルの代わりに読むのが簡単です。行の長さが1600文字である〜50行のファイルです。 – Shaun

答えて

0

whileループ以外のデータを定義し、最後のステータスを最後のファイルに書き込むことができます。こうすることで、データが保持している最後のステータス更新をファイルに書き込むだけで、ファイルの最終状態を常に上書きすることがなくなります。

import subprocess as sp 
import sys 
perl_script='/usr/.../foo.pl' 
p = sp.Popen(perl_script,stdout=sp.PIPE,stderr=sp.PIPE) 
fname='test.log' 
shell_out=True 
text = '' 
data = '' 

while True: 
    data = p.stdout.read(1) 
    if data == '' and p.poll() != None: 
     break 
    if data != '': 
     if shell_out is True: 
      sys.stdout.write(data) 
      sys.stdout.flush() 
    p.stdout.close() 
with open(fname, 'w') as log: 
    log.write(data) 
+0

これは、データは常に1文字であるため、このperlスクリプトの詳細については、ログファイルが '\ n'になります。ループの後に 'data'を追加して' data'を修正することもできましたが、 'stdout'を得てログファイルを書き込めるようにしたいと考えていました。 – Shaun

+0

あなたが行くようにしたいと思っている理由は何ですか?そして、その場合には[.strip()](https://docs.python.org/2/library/stdtypes.html#str.strip)を使用することができます – heinst

+0

私はそれについてもっと考えると、それほど重要ではないと思います'stdout'がキャプチャされたときにログファイルを書き込もうとしています。これを考えると、唯一の問題は、上書きされるすべての行を削除するようにテキストを書式設定する方法です。それに応じて元の投稿を更新します。 – Shaun

関連する問題