67

I have a command that produces output in color, and I would like to pipe it into a file with the color codes stripped out. Is there a command that works like cat except that it strips color codes? I plan to do something like this:

$ command-that-produces-colored-output | stripcolorcodes > outfile
4
  • 4
    It might be a bug that a program produces colored output even then it's output is redirected to a file and doesn't provide an option to switch it off. I'd expect any program that colors it's output to check isatty(stdin) before doing so. Mind to share what is that program?
    – alex
    Dec 4 '10 at 6:44
  • pass it through cat - quick test I ran grep --color=auto myusername /etc/passwd gives me my username in red with white text elsewhree. grep --color=auto myusername /etc/passwd | cat gives me plain white text
    – ivanivan
    Nov 15 '17 at 2:48
  • 2
    That's not a solution. It only works because grep --color=auto avoids producing colored output when standard output is not a terminal. I'm talking about a command that unconditionally outputs color codes. (As alex points out above, such behavior is arguably a bug, but sometimes we need to work with imperfect software that we can't easily fix ourselves, and that's what this question is about.) Nov 15 '17 at 4:00
  • Possibly relevant unix.stackexchange.com/questions/14684/… Jun 10 '18 at 14:22
62

You'd think there'd be a utility for that, but I couldn't find it. However, this Perl one-liner should do the trick:

perl -pe 's/\e\[?.*?[\@-~]//g'

Example:

$ command-that-produces-colored-output | perl -pe 's/\e\[?.*?[\@-~]//g' > outfile

Or, if you want a script you can save as stripcolorcodes:

#! /usr/bin/perl

use strict;
use warnings;

while (<>) {
  s/\e\[?.*?[\@-~]//g; # Strip ANSI escape codes
  print;
}

If you want to strip only color codes, and leave any other ANSI codes (like cursor movement) alone, use

s/\e\[[\d;]*m//g;

instead of the substitution I used above (which removes all ANSI escape codes).

2
32

Remove color codes (special characters) with GNU sed

sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"

Or

Strip ANSI escape sequences in Python

Install colorama python package (pip install colorama). Put into stripcolorcodes:

#!/usr/bin/env python
import colorama, fileinput, sys;
colorama.init(strip=True);

for line in fileinput.input():
    sys.stdout.write(line)

Run chmod +x stripcolorcodes.

1
  • 2
    Didn't try python, but the sed version doesn't strip all colors. (I didn't test exhaustively, but it left some background colors intact, so I went with the faster perl option.)
    – rsaw
    Jan 17 '18 at 23:48
22

If you can install the Term::ANSIColor module, this perl script works:

#!/usr/bin/env perl
use Term::ANSIColor qw(colorstrip);
print colorstrip $_ while <>;
3
  • 6
    That's actually where I got that color-codes-only regex. But installing a whole module just for that one regex is a bit much.
    – cjm
    Dec 4 '10 at 2:00
  • 4
    Meh, if you set up cpanm correctly, it installs the module in about 5 seconds. Dec 4 '10 at 9:30
  • 1
    There is no need to write the script to the file. Just pipe into: perl -mTerm::ANSIColor=colorstrip -n -e 'print colorstrip $_' Jun 25 '19 at 14:07
11

If your system has access to NodeJS you could install the following Node package, strip-ansi-cli.

$ npm install -g strip-ansi-cli

You can then run your command like so:

$ command-that-produces-colored-output | strip-ansi > outfile
3
  • 3
    NodeJS is a huge dependency, when there are solutions that can use languages and tools already present in most systems.
    – user137369
    Nov 14 '17 at 16:50
  • Also, this is the slowest solution listed (see here) and you probably will notice the difference.
    – user254560
    Nov 17 '17 at 8:23
  • It's worth noting that all this module does is replaces all matches of the regex string.replace(ansiRegex(), '') which is defined here github.com/chalk/ansi-regex/blob/main/index.js.
    – Andy
    Jun 13 at 2:23
3

This sed command did it for me:

sed -r "s/\\^\\[(\\[[^@-~]+[@-~]|[0-9@-_]|%@)//g"

Example:

$ command-that-produces-colored-output | sed -r "s/\\^\\[(\\[[^@-~]+[@-~]|[0-9@-_]|%@)//g" > outfile
1
  • This doesn't seem to work with the latest version of sed.
    – user254560
    Nov 17 '17 at 8:22
3

You can use ac for this. It should be faster than anything listed above (though perl and sed should be decent). Here's an example:

curl -s wttr.in/LA | ac -s

As a disclaimer: the color filtering functionality was written by me.

0
2
$ command-that-produces-colored-output | ansifilter

... and if necessary, (dnf, ...) install ansifilter

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.