How can I print over the current line in a command

2019-01-06 13:56发布

问题:

On Unix, I can either use \r (carriage return) or \b (backspace) to print over text already visible in the shell (i.e. overwrite the current line again).

Can I achieve the same effect in a Windows command line from a Python script?

I tried the curses module but it doesn't seem to be available on Windows.

回答1:

yes:

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()


回答2:

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.

And if on the IPython-notebook, just like this:

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



回答3:

I know this is old, but i wanted to tell my version (it works on my PC in the cmd, but not in the idle) to override a line in Python 3:

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

EDIT: It works on Windows and on Ubuntu



回答4:

I just had this problem. You can still use \r, even in Windows Command Prompt, however, it only takes you back to the previous linebreak (\n).

If you do something like this:

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

You'll get:

0
1
2
3
4
5
...

That's because \r only goes back to the last line. Since you already wrote a newline character with the last print statement, your cursor goes from the beginning of a new empty line to the beginning of the same new empty line.

To illustrate, after you print the first 0, your cursor would be here:

0
| # <-- Cursor

When you \r, you go to the beginning of the line. But you're already on the beginning of the line.

The fix is to avoid printing a \n character, so your cursor is on the same line and \r overwrites the text properly. You can do that with print 'text',. The comma prevents the printing of a newline character.

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

Now it will properly rewrite lines.

Note that this is Python 2.7, hence the print statements.



回答5:

easy method :)

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)


回答6:

Simple way if you're just wanting to update the previous line:

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


回答7:

On Windows (python 3), it seems to work (not using stdout directly):

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))

The same line is updated everytime print function is called.

This algorithm can be improved, but it is posted to show what you can do. You can modify the method according to your needs.



回答8:

Easiest way is to use two \r - one at the beginning and one at the end

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

It will go pretty quickly



回答9:

Thanks for all the useful answers in here guys. I needed this :)

I found nosklo's answer particularly useful, but I wanted something fully contained within a function by passing the desired output as a parameter. Also, I didn't really need the timer, since I wanted the printing to take place after a specific event).

This is what did the trick for me, I hope someone else finds it useful:

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()