5

In Python you can print on the same line using \r to move back to the start of the line.

This works well for progress bars or increasing precentage counters, eg: Python print on same line

However when printing lines that may decrease in length, this leaves the previous lines text there, eg:

import sys
for t in ['long line', '%']:
    sys.stdout.write(t + '\r')
sys.stdout.write('\n')

Leaves the terminal text as: %ong line.

Whats the best way to write a shorter line after a longer one, when printing to the same line?

ideasman42
  • 35,906
  • 32
  • 172
  • 287
  • 1
    Note that some of the answers to https://stackoverflow.com/questions/3249524 (lower down on the page), cover this question, but the question is in fact different. – ideasman42 Jul 23 '17 at 09:39

3 Answers3

6

Along with \r, the ansi-sequence \033[K is needed - erase to end of line.

This code works as expected.

import sys
for t in ['long line', '%']:
    sys.stdout.write('\033[K' + t + '\r')
sys.stdout.write('\n')

Note, this doesn't work when the string includes tabs, you may want to replace:

sys.stdout.write('\033[K' + t + '\r') with ...

sys.stdout.write('\033[K' + t.expandtabs(2) + '\r')

ideasman42
  • 35,906
  • 32
  • 172
  • 287
  • 1
    I found that the erase sequence interferes with space-expanded tabs unless you put it in a separate string like `print('\033[K' + '\tWords here'.expandtabs(2))` – Addison Klinke Dec 07 '20 at 19:51
  • Thanks for pointing this out, added note, I'm not sure if there is a better way to solve this than what you've suggested. – ideasman42 Dec 07 '20 at 22:28
  • Can you explain why you added the `\r` to the end of the string? I tried it with `print('\r\033[K'+t)` and it seems to work. – Manngo Apr 05 '22 at 23:56
  • It can be at the beginning of the line too, the cursor will then be left at the end. – ideasman42 Apr 06 '22 at 02:17
1

I think the simplest way to do this is to write spaces over the characters. For this, it'd be a good idea to write as many spaces are needed to cover the last line only. Example:

previousLength = 0
for t in ["long line", "%"]:
    print(" " * previousLength, end="\r") 
    print(t, end="\r")

    previousLength = len(t)

print("\n")
M Palmer
  • 181
  • 4
0

If you have been printing without a newline character at the end of your print, you can flush your latest print with:

print('\r\033[K', end='')

If you previously printed with a new line, you can use the ANSI escape code to move up one line and to the beginning of the line with:

print('\033[F', end='')

You can then flush the line as before.

An example usage:

LINE_FLUSH = '\r\033[K'
UP_FRONT_LINE = '\033[F'
...
print(UP_FRONT_LINE + LINE_FLUSH + msg)
ljden
  • 224
  • 1
  • 9