How to Programmatically "Burn In" Ansi Control Codes to a File Using Unix Utils

How to strip the ANSI escape codes from a text file?

This is not a direct answer to your question as you asked it, but I just wanted to note that terraform plan has a -no-color option which will disable the control codes and just emit plain text at the source, avoiding the need to strip the codes out later.

How to remove terminal control escape sequences in the file?

I solved this issue using lots of regular expressions according to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html

Bash - process backspace control character when redirecting output to file

Thanks for your comments! I ended up piping the output of that program to AWK Script I linked in the question. I get a well-formed file in the end.

the_program | ./awk_crush.sh > output.txt

The only downside is that I get the output only once the program itself is finished, even though the initial output exceeds 5M and should be passed in the lesser chunks. I don't know the exact reason, perhaps AWK script waits for EOF on stdin. Either way, on more modern system I would use

stdbuf -oL the_program | ./awk_crush.sh > output.txt

to process the output line-by-line. I'm stuck on RHEL4 with expired support though, so I'm unable to use neither stdbuf nor unbuffer. I'll leave it as-is, it's fine too.

The contents of awk_crush.sh are based on this answer, except with ^H sequences (which are supposed to be ASCII 08 characters entered via VIM commands) replaced with escape sequence \b:

#!/usr/bin/awk -f
function crushify(data) {
while (data ~ /[^\b]\b/) {
gsub(/[^\b]\b/, "", data)
}
print data
}

crushify($0)

Basically, it replaces character before \b and \b itself with empty string, and repeats it while there are \b in the string - just what I needed. It doesn't care for other escape sequences though, but if it's necessary, there's a more complete SED solution by Thomas Dickey.

How to pull the output of the most recent terminal command?

The shell (and terminals) by themselves will not do this for you.

I'd wrap the command in a shell-script which calls the script command, e.g.,

  • create a temporary filename (system-dependent, but for example with mktemp),
  • use that temporary file as the output for script, rather than the default typescript.
  • in the command passed to script, echo the exit-code since script will hide that from you
  • in the shell-script, filter out carriage-returns, etc., e.g., with script2log, and
  • the last line of the filtered output would have the exit-code. Use that for the exit-code of the shell-script

For your CLI program, make the shell-script accept a parameter which tells the shell-script where to write the output of the command. Likely that is another temporary file, avoiding the problem of redirecting the output of the command to a file or pipe, making the output no longer a terminal.

If you're using the Linux variant of script, it could be something like this:

#!/bin/sh
# $1 = command
# $2 = output
code=0
tempfile=$(mktemp)
trap "rm -f \$tempfile; exit \$code" EXIT INT QUIT HUP
script -q -c "$1; echo \$?" $tempfile
script2log <$tempfile >$2
code=$(tail -n 1 $tempfile)

How can I use script to create a typescript of my terminal session?

script records all characters sent to your terminal. That includes all kinds of terminal control sequences (such as cursor movement, colors, etc).

By default, less (and other pages) do not work well with these control characters. Use the -R option of less to allow the program to render the file as it was originally sent. There are some limitations, since even this presumes that the file is not generated in fullscreen mode. To handle that, your best choice is to slowly cat the file to a terminal with the same size as that on which the file was generated. For that, I use a program slowcat. Others use a -t option to script which records timing information (but that is not available on all versions of script — essentially, Linux-specific).

Alternatively, you can use a program or script to remove these control sequences, and get something comparable (without video highlights and colors) to that which less -R would show. Some discussion of how to do this is found in Can I programmatically “burn in” ANSI control codes to a file using unix utils?.

UNIX script command includes gibberish in export

It's not that simple, but you can transform the file on the Unix side, e.g., using sed. unix2dos and iconv solve a different problem than this, and cannot help with it.

There are several related answers, but I prefer the script which I wrote to answer Can I programmatically “burn in” ANSI control codes to a file using unix utils?.

The script is described briefly on one of my webpages, with some examples. It can be downloaded from that page, in a gzip'd tarfile.

Starting with the tarball...

tar xf misc-scripts.tar.gz
mv misc-scripts-2*/script2log .
rm -rf misc-scripts-2*

(unless you are interested in the other scripts: the tarball is simply a snapshot with files up to a given date which expands to a directory named with that date).

To use it, put script2log in your path, or just run it:

./script2log typescript >plaintext.log

or

./script2log -o plaintext.log typescript


Related Topics



Leave a reply



Submit