如何在命令行应用程序中打印当前行?

时间:2009-01-21 13:43:18

标签: python windows command-line

在Unix上,我可以使用\ r(回车)或\ b(退格)来打印shell中已经可见的文本(即再次覆盖当前行)。

我可以从Python脚本在Windows命令行中实现相同的效果吗?

我尝试了curses模块,但它似乎在Windows上不可用。

10 个答案:

答案 0 :(得分:28)

是:

import sys
import time

def restart_line():
    sys.stdout.write('\r')
    sys.stdout.flush()

sys.stdout.write('some data')
sys.stdout.flush()
time.sleep(2) # wait 2 seconds...
restart_line()
sys.stdout.write('other different data')
sys.stdout.flush()

答案 1 :(得分:12)

import sys 
import time

for i in range(10):
    print '\r',         # print is Ok, and comma is needed.
    time.sleep(0.3)
    print i,
    sys.stdout.flush()  # flush is needed.

如果在IPython-notebook上,就像这样:

import time
from IPython.display import clear_output

for i in range(10):
    time.sleep(0.25)
    print(i)
    clear_output(wait=True)

http://nbviewer.ipython.org/github/ipython/ipython/blob/master/examples/notebooks/Animations%20Using%20clear_output.ipynb

答案 2 :(得分:6)

我知道这已经过时了,但是我想告诉我的版本(它在我的电脑上在cmd中运行,但不在空闲状态下)来覆盖Python 3中的一行:

>>> from time import sleep
>>> for i in range(400):
>>>     print("\r" + str(i), end="")
>>>     sleep(0.5)

修改 它适用于Windows和Ubuntu

答案 3 :(得分:5)

我刚遇到这个问题。即使在Windows命令提示符下,您仍然可以使用\r,但它只会将您带回上一个换行符(\n)。

如果您这样做:

cnt = 0
print str(cnt)
while True:
    cnt += 1
    print "\r" + str(cnt)

你会得到:

0
1
2
3
4
5
...

那是因为\r只回到最后一行。由于您已经使用最后一个print语句编写了换行符,因此光标从新的空行开始到同一个新空行的开头。

为了说明,在打印第一个0后,光标将在此处:

0
| # <-- Cursor

当您\r时,您会转到该行的开头。但是你已经在线的开头了。

修复是为了避免打印\n字符,因此光标位于同一行,\r会正确覆盖文本。您可以使用print 'text',执行此操作。逗号可以阻止打印换行符。

cnt = 0
print str(cnt),
while True:
    cnt += 1
    print "\r" + str(cnt),

现在它会正确地重写行。

请注意,这是Python 2.7,因此是print语句。

答案 4 :(得分:5)

简单方法:)

import sys
from time import sleep
import os

#print("\033[y coordinate;[x coordinateH Hello")
os.system('cls')
sleep(0.2)
print("\033[1;1H[]")
sleep(0.2)
print("\033[1;1H  []")
sleep(0.2)
print("\033[1;1H    []")
sleep(0.2)
print("\033[1;1H      []")
sleep(0.2)
print("\033[1;1H        []")
sleep(0.2)
print("\033[1;1H      []")
sleep(0.2)
print("\033[1;1H    []")
sleep(0.2)
print("\033[1;1H  []")
sleep(0.2)
print("\033[1;1H[]")
sleep(0.2)

答案 5 :(得分:2)

如果您只是想更新上一​​行,那么只需简单的方法:

import time
for i in range(20):
    print str(i) + '\r',
    time.sleep(1)

答案 6 :(得分:1)

在Windows(python 3)上,它似乎工作(不直接使用stdout):

import sys

for i in reversed(range(0,20)):
  time.sleep(0.1)
  if(i == 19):
    print(str(i), end='', file=sys.stdout)
  else:
    print("\r{0:{width}".format(str(i), width = w, fill = ' ', align = 'right'), end='', file=sys.stdout)
  sys.stdout.flush()
  w = len(str(i))

每次调用print函数时都会更新相同的行。

此算法可以改进,但会发布以显示您可以执行的操作。您可以根据需要修改方法。

答案 7 :(得分:1)

最简单的方法是在开头使用两个\ r - 一个

for i in range(10000):
    print('\r'+str(round(i*100/10000))+'%  Complete\r'),

它会很快进行

答案 8 :(得分:0)

感谢这里的所有有用的答案。我需要这个:))

我发现nosklo的答案特别有用,但我希望通过将所需的输出作为参数传递,完全包含在函数中。此外,我并不真正需要计时器,因为我希望在特定事件之后进行打印。

这就是我的诀窍,我希望其他人觉得它很有用:

import sys

def replace_cmd_line(output):
    """Replace the last command line output with the given output."""
    sys.stdout.write(output)
    sys.stdout.flush()
    sys.stdout.write('\r')
    sys.stdout.flush()

答案 9 :(得分:0)

是的,这个问题是11年前提出的,但是很酷。我喜欢即兴创作。 附加到nosklo的答案:

import sys
import time

def restart_line():
    sys.stdout.write("\r")
    sys.stdout.flush()

string_one = "some data that is very long..."
sys.stdout.write(string_one)
sys.stdout.flush()

time.sleep(2)
restart_line()

string_two = "shorter data"
if len(string_two) < len(string_one):
    string_two = string_two+(" "*int((len(string_one)-len(string_two))))
    # This will overwrite the characters that would be left on the console

sys.stdout.write(string_two)
sys.stdout.flush()