1

Say I have the string '\033[2KResolving dependencies...\033[2KResolving dependencies...'

In the Python console, I can print this, and it'll only display once

Python 3.10.9 (main, Jan 19 2023, 07:59:38) [GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> output = '\033[2KResolving dependencies...\033[2KResolving dependencies...'
>>> print(output)
                         Resolving dependencies...

Is there a way to get a string that consists solely of the printed output? In other words, I would like there to be some function

def evaluate_ansi_escapes(input: str) -> str:
    ...

such that evaluate_ansi_escapes(output) == 'Resolving dependencies...' (ideally with the correct amount of whitespace in front)


edit: I've come up with the following stopgap solution

import re

def evaluate_ansi_escapes(input: str) -> str:
    erases_regex = r"^.*(\\(033|e)|\x1b)\[2K"
    erases = re.compile(erases_regex)
    no_erases = []
    for line in input.split("\n"):
        while len(erases.findall(line)) > 0:
            line = erases.sub("", line)
        no_erases.append(line)
    return "\n".join(no_erases)

This does successfully produce output that is close enough to I want:

>>> evaluate_ansi_escapes(output)
'Resolving dependencies...'

But I would love to know if there is a less hacky way to solve this problem, or if the whitespace preceding 'Resolving dependencies...' can be captured as well.

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
wrongusername
  • 18,564
  • 40
  • 130
  • 214
  • 1
    Related: [How can I remove the ANSI escape sequences from a string in python](https://stackoverflow.com/q/14693701/674039) and [Printed length of a string in python](https://stackoverflow.com/q/14889454/674039) – wim Feb 19 '23 at 02:20
  • @wim thanks! the solution in the first one produces `'Resolving dependencies...Resolving dependencies...'`, which is not quite what I want since the string is still duplicated. Ditto for the second one :) – wrongusername Feb 19 '23 at 02:29
  • Yeah, I did not really find any good answer myself (which is why there is no accepted answer on the second one). For this question, shouldn't the correct result be `" Resolving dependencies..."`? There is whitespace printed too. – wim Feb 19 '23 at 02:33
  • @wim that's true, I'll update the question to make it clear that this is close enough to what I want, but not quite it – wrongusername Feb 19 '23 at 02:55
  • What would you expect this function to return for codes that, say, repositioned the cursor to the line before the previous output? – Davis Herring Feb 19 '23 at 15:27
  • @DavisHerring ideally it would be able to return the final output text displayed by the terminal, but I realize that doing so with my current method would require effectively simulating the effects of each and every ANSI escape code. It would be nice if there were a way to avoid that – wrongusername Feb 19 '23 at 22:06
  • @wrongusername: The “final output text” could easily include various characters already on the glass, which you don’t know. – Davis Herring Feb 20 '23 at 01:24
  • @DavisHerring what does "on the glass" mean? Characters already part of terminal output? Perhaps, but I'm looking for something that's as close an approximation as reasonable to the output from `print(...)`. – wrongusername Mar 03 '23 at 04:39
  • @wrongusername: Yes, previous output that could be intermixed with the characters written by the current `print` because of cursor positioning. It’s hard to even say what’s “as close an approximation as reasonable” to that without the full state of the terminal being available. (Would your output scroll the terminal before repositioning into some previous text? Do you have the scroll on writing to the last cell disabled?) – Davis Herring Mar 03 '23 at 05:28

0 Answers0