I'm trying to get the output of a program (which has colors) and output it with tee
. I want the output to have colors on the terminal (stdout) but not on the output file. Is this possible?
-
What program are you running? – choroba Nov 06 '12 at 16:55
-
It's a script I wrote (it's really long); I just want to `tee` it's output to a file and to the screen but have colors on the screen. – pap42 Nov 06 '12 at 16:55
-
How do you print colors in the script? – choroba Nov 06 '12 at 17:04
-
@choroba: google for "bash colors" – anishsane Nov 07 '12 at 08:11
-
@anishsane: The answer would be different for different ways of producing the colors (echoing ANSI codes, grepping, ls-ing...). – choroba Nov 07 '12 at 08:23
-
AFAIK, grep, ls - all use ANSI codes for colors on terminal. – anishsane Nov 07 '12 at 08:28
-
6this link is the answer http://superuser.com/a/751809/163119, why did people think this is not a real question? – Kokizzu Nov 21 '14 at 03:16
-
Use "unbuffer", part of the "expect" package. In Ubuntu, I just installed that package using `sudo apt-get install expect-dev`. I will post an answer about this as soon as the question is unlocked. See http://stackoverflow.com/questions/5073081/how-can-i-pipe-from-terminal-in-perl-without-losing-color – Mihai Danila Nov 21 '14 at 20:54
-
The question mentioned in @Kokizzu's comment is helpful, but different -- this question states they want no colors in the output file; the linked question http://superuser.com/a/751809/163119 states they don't care about color codes in the output, and the answer is accordingly. – Aaron Wallentine Feb 02 '22 at 03:34
2 Answers
A possible approach is, to print the escape characters on stderr, & main contents on stdout. I had done it in one of the script. It's of-course not a scalable option.
It would be an interesting exercise to write a dedicated script, which parses stdin, puts escape sequences on stderr & others on stdout. :-)
Then
./myScript.sh | filter_escapes | tee outfile.log
I have not seen any script which does that, but I think, it would be interesting to write one, if not already available.
As far as your question is concerned, I think below should suffice:
ls --color=always | sed -r 'w /dev/stderr' | sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' > /tmp/test
replace ls --color=always
with ./your_script & /tmp/test
with your intended output file name.
Other implementation:
ls --color=always | tee >(sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' > /tmp/abcd)
Note: tee >(sed .... > logfile)
syntax
Note:
- regex borrowed from sampson-chen's answer.
- w command for /dev/stderr in sed is GNU sed's addition.

- 20,270
- 5
- 40
- 73
-
-
Uh... I don't remember downvoting. Sorry. Perhaps I was grumpy that day. Now I can't seem to undo it. – nroose Mar 05 '16 at 20:12
-
Nevermind... I thought there was some mistake in the solution or that I was suggesting bad coding practice. So, when someone downvotes a question/answer, a comment is requested, for improvement reasons. – anishsane Mar 07 '16 at 05:10
Yes, it's possible. Pipe the results you want to go into the output file through sed
to remove the escape characters used in formatting colors:
On Linux:
sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
On OS X since it's not GNU sed:
sed -E "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
A part of a tool I wrote recently does exactly what you described with tee
:
https://github.com/sampson-chen/sack/blob/master/sack
ack --color $sack__flags $@ $sack__cwd | tee >$sack__dev_null >(display_shortcuts) >(process_shorcut_paths | remove_escaped_chars > $sack__shortcut_file)
where the function remove_escaped_chars
contains a check for OS version, then applies the sed
script as seen above.
(Note 1: tee
redirects a copy of output to stdout automatically, so I used >$sack__dev_null
to prevent that: because I wanted add additional information to the stuff printed to stdout, as defined in the function display_shortcuts
)
(Note 2: tee
itself definitely never removed the color formatting when I used it: My suspicion is other tools' default behaviour with pipes.)

- 45,805
- 12
- 84
- 81
-
Thanks for the reply; at the moment, what I'm getting is the opposite of what you're thinking. I am printing *with* colors but `tee` is removing them both from the stdout and from the output file. In other words, I am trying to do the opposite of what you suggested (the output file looks fine; it's the stdout which is not behaving the way I want) – pap42 Nov 06 '12 at 17:10
-
2@pap42 which tools are you using in your script that produces the color formatting? Tools like `grep` for example will turn off color formatting by default when used as part of a pipe (you can test this by using grep to find something, then piping it to another grep). To preserve color formatting through pipes, you'll have to see if these tools have some option to do so (such as `grep`'s `--color=always` option). `tee` itself definitely never removed the color formatting when I used it: My suspicion is other tools' default behaviour with pipes. – sampson-chen Nov 06 '12 at 17:16
-
Actually, I'm outputting stuff with colors directly with `tee`. The stuff that goes to stdout does not have colors... – pap42 Nov 06 '12 at 17:57
-
http://stackoverflow.com/questions/5073081/how-can-i-pipe-from-terminal-in-perl-without-losing-color – Mihai Danila Nov 21 '14 at 20:54