web-dev-qa-db-ja.com

Windowsコマンドラインの現在の行を上書き/印刷するにはどうすればよいですか?

Unixでは、\r(キャリッジリターン)または\b(バックスペース)を使用して、シェルの現在の行(既に表示されているテキストの上に印刷)を上書きできます。

PythonスクリプトからWindowsコマンドラインで同じ効果を達成できますか?

Cursesモジュールを試しましたが、Windowsでは使用できないようです。

18
Aaron Digulla

はい:

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()
28
nosklo
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ノートブックの場合、次のようになります。

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

12
Honghe.Wu

私はこれが古いことを知っていますが、Python 3:

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

編集: WindowsとUbuntuで動作します

8
adho12

簡単な方法:)

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

私はちょうどこの問題を抱えていました。 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ステートメントであることに注意してください。

5
Anubian Noob

前の行を更新したいだけの場合の簡単な方法:

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

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

印刷関数が呼び出されるたびに同じ行が更新されます。

このアルゴリズムは改善できますが、何ができるかを示すために投稿されています。必要に応じてメソッドを変更できます。

1
Jesufer Vn

最も簡単な方法は、2つの\ rを使用することです。1つは最初に、もう1つは最後に使用します。

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

それはかなり速く行きます

1
bfree67

ここにいるみんなの役に立つ答えをありがとう。私はこれが必要でした:)

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