Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
How to overwrite lines of STDOUT in Python?
print()
normally adds text to STDOUT, it does not erase existing text.
https://linux.codidact.com/posts/289869 describes various ways of doing the overwrite in shell scripts.
How can you do this in Python?
2 answers
The solution proposed by the other answer works, but there's a corner case. If the last message is shorter than the previous one, you might not get what you want. Example:
print("this is some text", end="\r")
print("abc")
Testing this in a Linux terminal, the output is:
abcs is some text
But I guess it should be only "abc", right? The rest of this answer assumes that that's the case.
IMO, the following isn't a pretty solution, but anyway: you could workaround this by printing lots of spaces before the next message (using the previous message's length to know how many spaces to use). For example, assuming the script is reading from stdin
:
last_line = ''
for line in map(str.rstrip, sys.stdin): # read from stdin, strip new line at the end
print(' ' * len(last_line), end='\r') # spaces to "clear" the line
print(line, end='\r')
last_line = line
print() # just to print a newline after the last line
Even though, in the case of a previous message bigger than the last one, there'll be extra spaces in the end (not visible, but still extra characters, which might or might not make a difference, depending on what you need).
A better solution, IMO, is to use the ANSI escape sequence \033[K
to clear the line before printing the next message:
for line in map(str.rstrip, sys.stdin): # read from stdin, strip new line at the end
print(f"\033[K{line}", end='\r')
print()
With this solution, the first example will be:
print("this is some text", end="\r")
print("\033[Kabc")
In this case, the output isn't abcs is some text
anymore, as the ANSI escape sequence clears the line before printing the rest, so the output is just abc
.
Older versions of Windows don't support ANSI escape sequences, and for those, one solution is to use an external library, such as Colorama:
# external lib, install it with "pip install colorama"
import colorama
colorama.just_fix_windows_console()
print("this is some text", end="\r")
print(f"{colorama.ansi.clear_line()}abc")
0 comment threads
The following users marked this post as Works for me:
User | Comment | Date |
---|---|---|
matthewsnyder | (no comment) | Oct 8, 2023 at 00:53 |
You can use the carriage return control character "\r"
to return to the beginning of the line and overwrite text.
When using the print
function you additionally have to make sure not to write the line feed control character ("\n"
) is not printed.
The easiest way to achieve this is probably to use the end
keyword argument as follows:
print("this is some text", end="\r")
print("this is a test", end="\r")
print("this is the final overwrite")
Note that after printing the last line (which uses end="\n"
by default), it will no longer be possible to overwrite anything on this line.
1 comment thread