简体   繁体   English

Bash或Python,在终端上打印字符时,如何在固定位置更改字符?

[英]Bash or Python, When print characters to terminal, how to CHANGE a character at a FIXED position?

The thing I want to know here should be really 'basic', but it is a question in my mind for long time and no idea where the trick is. 我想在这里知道的东西应该真的是“基本的”,但这是我很长一段时间以来一直在思考的一个问题,不知道窍门在哪里。

Let's say in a time-consuming program(either bash or Python ), I have to print out the percentage of the progress when it's running, and basically I want to print 1% , and after a certain time, I print 2% , etc.. I want '2%' to be displayed exactly at the same position where '1%' was displayed, rather than they're like "1% 2%" or whatever. 假设在一个耗时的程序( bashPython )中,我必须在运行时打印出进度的百分比,基本上我想打印1% ,在一定时间后,我打印2% ,等等..我希望将'2%'准确显示在显示'1%'位置,而不是像“ 1%2%”之类的东西。 You know wget , what I want is exactly what wget does, to show the progress of the downloading progress. 您知道wget ,我想要的正是wget的功能,以显示下载进度。 Do I need to clear the previously printed character, but how? 我需要清除以前打印的字符,但是如何清除?

How does it work basically... 基本上如何运作...

Thanks, 谢谢,

I'm going to answer in Python, since it's easier. 我要用Python回答,因为它更容易。

You can print a backspace to the terminal to move the cursor to the left, and then write another character to overwrite the current position. 您可以在终端上打印退格键,以将光标向左移动,然后写入另一个字符以覆盖当前位置。 You can also use a carriage return to go to the beginning of the line. 您也可以使用回车键转到行首。

import time
import sys
for x in range(101):
    sys.stdout.write('\r%d%%' % x)
    sys.stdout.flush()
    time.sleep(0.2)
sys.stdout.write('\n')

Using a carriage return and rewriting the whole line is the easiest, since you don't have to be careful about how many backspaces to print. 使用回车并重写整行是最简单的,因为您不必担心要打印多少个退格键。

Note that if the new line is shorter than the old line, the old line will still show through. 请注意,如果新行比旧行短,则旧行仍会显示出来。

import sys
sys.stdout.write('this is a very long line')
sys.stdout.write('\rshort line')
sys.stdout.write('\n')

Output: 输出:

short linevery long line

A typical solution is to write spaces over the long line. 一个典型的解决方案是在长行上写空格。

A Python solution has been offered, it is not particularly difficult (or different) in bash: 提供了Python解决方案,在bash中并不是特别困难(或不同):

i=20
while (( i-- ))
do
    echo -ne "\r$i% done  "
    sleep 1
done

echo

The flush is not required in bash because that's invoked by echo anyway. bash中不需要flush ,因为无论如何它都是由echo调用的。 The arguments to echo , -n supresses a new-line, and -e translates the \\r notation. echo-n的参数禁止换行, -e转换\\r表示法。 Note the hack with a couple of spaces at the end of the text in the string, to clear to end-of-line. 请注意,在该字符串的文本末尾有几个空格的hack可以清除到行尾。

this is a simple timer perhaps help you ;-) write another character to overwrite the current position with print function. 这是一个简单的计时器,也许会对您有所帮助;-)用打印功能编写另一个字符以覆盖当前位置。

from __future__ import print_function
def timer():
 for h in range(0, 24):
  for m in range(0, 60):
   for s in range(0, 60):
    time.sleep(1)
    print ("Elapsed time : %s:%s:%s" % (h, m, s), end="\r")

In Python 3.6+, Deitrich's answer can be shortened to 在Python 3.6+中,Deitrich的答案可以简化为

import time
for i in range(101):
    print(f'\r{i}%', end='')
    time.sleep(0.01)

The carriage return takes you back to the beginning of the line, and passing in an empty string as the end parameter stops you from moving to the next line. 回车使您返回到行的开头,并传递一个空字符串作为end参数,使您无法移至下一行。


I also find this generator useful when I don't know how long an action will take. 当我不知道一个动作要花多长时间时,我也觉得这个生成器很有用。 It will print out the three dots loading animation. 它将打印出加载动画的三个点。 Works in Python 3.3+ 适用于Python 3.3+

def loading_dots():
    while True:
        yield("\r.  ")
        yield("\r.. ")
        yield("\r...")

You would use it like this 你会这样使用

max_attempts = 100
dots = loading_dots()

for i in range(max_attempts):
    if is_finished(): # you would have to create this function
        break
    time.sleep(2)
    print(next(dots), end="", flush=True)
else:
    raise Exception("timed out")

And if you ever want to clear the current line, you can do so like this (Python 3.3+) 而且,如果您想清除当前行,可以这样做(Python 3.3+)

print('\r' + ' '*80 + '\r', end='')

I Think The Better Answer For This Question Is : 我认为这个问题的更好答案是:

import time

for i in range(101):
    print(f"\r{i}%",end='')
    time.sleep(0.1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python - 将特殊字符插入 JSON 字符串以在 bash 终端上打印它们 - Python - Inserting special characters into JSON string to print them on bash terminal 运行python脚本时,为什么在Bash或zsh终端中json中的字符发生变化? - Why is there a character in json change in Bash or zsh terminal when running a python script? 使用python 3在终端中打印unicode字符 - print unicode characters in terminal with python 3 Python:如何在固定字符串中的特定字符之前排除一组字符 - Python: How to exclude a group of characters before a specific character in a fixed string (python和jes)如果两个字符相同,如何查找字符在字符串中的位置? - (python and jes) How to find the position of a character in a string if 2 characters are the same? 在 VSCODE 中将 Python 终端从 Bash 更改为 CMD - Change the Python Terminal from Bash to CMD in VSCODE 打印输出时,curosr的位置始终固定为(0,0)-Pygame(Python 2.7) - Position of curosr when print out is always fixed at (0,0) - Pygame (Python 2.7) 如何从python打印\\ [和\\]到终端? - How to print \[ and \] to terminal from python? 如何在字符串中的某个位置更改字符... Python - How to change characters in a certain position within a string… Python python bash如何转义字符'?'? - python bash how to escape character '!'?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM