Python:将进度条写入文件

Python:将进度条写入文件,python,Python,我有一个python脚本,作为它的一部分,它运行一个perl脚本。我正在使用子流程模块执行和捕获stdout和stderr;伪代码是: 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

我有一个python脚本,作为它的一部分,它运行一个perl脚本。我正在使用
子流程
模块执行和捕获
stdout
stderr
;伪代码是:

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()
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)
对于循环的每次迭代,数据似乎都是单个字符串

我遇到的问题是,这个perl脚本显示了一个它覆盖的进度条;比如:

[#####.....] 50%
每5%更新一次。因此,我写入的日志文件最终包含以下内容:

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

是否有一种方法或方法可以让我在日志文件中的前一行上进行写操作,或者是我唯一可以捕获所有文本,尝试修改它,然后将其写入日志文件的选项

编辑:我认为我给出的例子的简单性质可能无法说明整个故事。这个perl脚本有多个进度条(每个任务一个进度条),并输出我想要记录的附加信息。更详细的例子是:

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脚本的stdout特征相匹配的示例,实际输出(我无法发布)大约有100行

最后,感谢您提供的格式帮助:)

编辑#2:我放弃了在捕获
stdout
时编写日志文件,而是将
stdout
存储在变量中,并在脚本完成后编写日志文件。剩下的唯一问题是如何正确格式化字符串,以便正确写入日志文件。更新后的伪代码为:

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()
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
写入文件,但我希望避免这种情况(我相信这种方法已不再使用)。

您可以在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)

您可以在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)

为什么要写日志文件中的行?@nathan.meadows-如果我不写日志文件中的行,那么就不要写一个易于阅读的100行文件,这是一个50行左右的文件,其中有些行长约1600个字符。为什么要在日志文件中的行上写?@nathan.meadows-如果我不在日志文件中的行上写,那么就不用一个易于阅读的100行左右的文件,这是一个大约50行的文件,其中有些行的长度大约为1600个字符。问题是数据总是一个字符,因此对于这个perl脚本的细节,这将导致一个日志文件,它只是
\n
。我可以在每次迭代中附加一个
数据
,然后在循环后修改
数据
,但我希望能够在得到
标准输出时编写日志文件。你想这样做的理由是什么?在这种情况下可能很有用我想得越多,就越不想在
stdout
被捕获时编写日志文件。考虑到这一点,唯一的问题是如何格式化文本以删除所有被覆盖的行。我将相应地更新我的原始帖子。问题是数据总是一个字符,因此对于这个perl脚本的细节,这将导致一个日志文件,它只是
\n
。我可以在每次迭代中附加一个
数据
,然后在循环后修改
数据
,但我希望能够在得到
标准输出时编写日志文件。你想这样做的理由是什么?在这种情况下可能很有用我想得越多,就越不想在
stdout
被捕获时编写日志文件。考虑到这一点,唯一的问题是如何格式化文本以删除所有被覆盖的行。我会相应地更新我原来的帖子。