Programa que passa STDIN para STDOUT com códigos de cores despojados?

64

Eu tenho um comando que produz saída em cores e gostaria de inseri-lo em um arquivo com os códigos de cores removidos. Existe um comando que funciona assim, catexceto que retira códigos de cores? Eu pretendo fazer algo assim:

$ command-that-produces-colored-output | stripcolorcodes > outfile
Ryan Thompson
fonte
4
Pode ser um erro que um programa produza saída colorida, mesmo assim ela é redirecionada para um arquivo e não fornece uma opção para desativá-la. Eu esperaria que qualquer programa que colorisse sua saída fosse verificado isatty(stdin)antes de fazê-lo. Se importa de compartilhar o que é esse programa?
alex
passe-o cat- o teste rápido que executei grep --color=auto myusername /etc/passwdme dá meu nome de usuário em vermelho com texto branco elsewhree. grep --color=auto myusername /etc/passwd | catme dá texto branco simples
ivanivan 15/11
11
Isso não é uma solução. Só funciona porque grep --color=autoevita produzir saída colorida quando a saída padrão não é um terminal. Estou falando de um comando que gera incondicionalmente códigos de cores. (Como aponta alex acima, tal comportamento é sem dúvida um erro, mas às vezes precisamos de trabalhar com software imperfeito que não podemos facilmente corrigir a nós mesmos, e é isso que esta questão é sobre.)
Ryan Thompson
Possivelmente relevante unix.stackexchange.com/questions/14684/…
Chris Stryczynski

Respostas:

59

Você pensaria que haveria um utilitário para isso, mas eu não consegui encontrá-lo. No entanto, este one-liner Perl deve fazer o truque:

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

Exemplo:

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

Ou, se você quiser um script, poderá salvar como stripcolorcodes:

#! /usr/bin/perl

use strict;
use warnings;

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

Se você deseja remover apenas códigos de cores e deixar outros códigos ANSI (como o movimento do cursor) em paz, use

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

em vez da substituição que usei acima (que remove todos os códigos de escape ANSI).

cjm
fonte
9
Como mencionado em um comentário para outra resposta ( unix.stackexchange.com/questions/4527/… ), esse regex foi retirado Term::ANSIColor. Reconheça suas fontes, por favor!
forivall
2
reconheça suas fontes!
Jürgen Paul
29

Remova os códigos de cores (caracteres especiais) com o GNU sed

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

Ou

Tirar seqüências de escape ANSI em Python

Instale o pacote colorama python ( pip install colorama). Coloque em stripcolorcodes:

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

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

Corra chmod +x stripcolorcodes.

jfs
fonte
Isso é incrível. Exatamente o que eu precisava!
precisa saber é o seguinte
O Python é um pouco lento, mas o sedé impressionante :) #
2
Não tentei python, mas a versão sed não tira todas as cores. (Eu não testar exaustivamente, mas deixou algumas cores de fundo intacto, então eu fui com a opção mais rápida perl.)
rsaw
22

Se você pode instalar o módulo Term :: ANSIColor , este script perl funcionará:

#!/usr/bin/env perl
use Term::ANSIColor qw(colorstrip);
print colorstrip $_ while <>;
Ryan Thompson
fonte
5
Foi aí que eu consegui aquela regex apenas de códigos de cores. Mas instalar um módulo inteiro apenas para esse regex é um pouco demais.
cjm
4
Meh, se você configurar o cpanm corretamente, ele instalará o módulo em cerca de 5 segundos.
Ryan Thompson
Não há necessidade de escrever o script no arquivo. Basta entrar em:perl -mTerm::ANSIColor=colorstrip -n -e 'print colorstrip $_'
Jesse Glick
10

Se o seu sistema tiver acesso ao NodeJS, você poderá instalar o seguinte pacote do Node strip-ansi-cli,.

$ npm install -g strip-ansi-cli

Você pode executar seu comando da seguinte maneira:

$ command-that-produces-colored-output | strip-ansi > outfile
David McNamara
fonte
11
O NodeJS é uma dependência enorme, quando existem soluções que podem usar linguagens e ferramentas já presentes na maioria dos sistemas.
user137369
Além disso, esta é a solução mais lento listados (ver aqui ) e você provavelmente vai notar a diferença.
3

Este comando sed fez isso por mim:

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

Exemplo:

$ command-that-produces-colored-output | sed -r "s/\\^\\[(\\[[^@-~]+[@-~]|[0-9@-_]|%@)//g" > outfile
Ben
fonte
Isso não parece funcionar com a versão mais recente do sed.
3

Você pode usar ac para isso. Deve ser mais rápido do que qualquer coisa listada acima (embora perle seddeva ser decente). Aqui está um exemplo:

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

Como um aviso: a funcionalidade de filtragem de cores foi escrita por mim.


fonte
3
um link para 'ac' será útil. ;)
Vitaly Kushner
O acprograma parece estar aqui: hub.darcs.net/vmchale/fastcat
Michael Burr
1
$ command-that-produces-colored-output | ansifilter

... e se necessário, (dnf, ...) install ansifilter

JJoao
fonte