3

I'm running a program that prints lots of escape characters (like "Esc[1A", to move the cursor up one line), and trying to redirect the output to a log file. When I run the program without redirection, the final output looks something like this:

256 lines processed.

But when I redirect to a log file, this is what the file ends up looking like:

Processing line 1...
Esc[1AProcessing line 2...
Esc[1AProcessing line 3...
...
Esc[1AProcessing line 256...
Esc[1A256 lines processed.

What's happening is that on the terminal, the "Esc[1A" character is telling the cursor to back up, so that each successive line overwrites the last line, and in the end, only the last line is displayed.

I want to have the log file appear exactly as the final output of the program would appear without redirection. I know it's possible to pipe the output to col -bp in order to filter out the escape characters, but I'd like to actually apply them, so that my log files don't end up containing thousands of extraneous lines. How can I achieve this?

1

You have to clear those escapes as you read them - do what the terminal does and overwrite them.

This emulates the output you describe w/ seq:

seq -s "
$(printf '\033[A')" 10

If it writes out to a terminal which interprets that escape it will appear to print only 10. But as you note in the question, it's really printing all of those numbers over one another. However, if I filter its output with sed like:

seq -s "
$(printf '\033[A')" 10 |
sed -e :n -e "\$!N;s/.*$(printf '\033\[A')//;tn"

...it really does print only 10 because sed continually reads in each next line of input and s///ubstitutes away everything from the head of pattern space to the last occurring key up escape. And each time it does so successfully, it branches back to the :n label to try again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.