Removendo códigos de cores ANSI do fluxo de texto


73

Examinando a saída de

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";'

em um editor de texto (por exemplo, vi) mostra o seguinte:

^[[37mABC
^[[0m

Como remover os códigos de cores ANSI do arquivo de saída? Suponho que a melhor maneira seria canalizar a saída através de um tipo de editor de fluxo.

O seguinte não funciona

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";' | perl -pe 's/\^\[\[37m//g' | perl -pe 's/\^\[\[0m//g'

Não é uma resposta para a pergunta, mas você também pode canalizar a saída moreou less -Rinterpretar os códigos de escape como cores em vez de como um editor de texto.
terdon

Respostas:


98

Os caracteres ^[[37me ^[[0mfazem parte das seqüências de escape ANSI (códigos CSI) . Veja também estas especificações .

Usando GNU sed

sed 's/\x1b\[[0-9;]*m//g'
  • \x1b(ou \x1B) é o caractere especial de escape
    ( sednão suporta alternativas \ee \033)
  • \[ é o segundo caractere da sequência de escape
  • [0-9;]* é o (s) valor (es) de cor regex
  • m é o último caractere da sequência de escape

Mac No macOS, o sedcomando padrão não suporta caracteres especiais, como \eindicado por slm e steamer25 nos comentários. Em vez disso, use gsedque você pode instalar usando brew install gnu-sed.

Exemplo com a linha de comando do OP:   (OP significa Pôster original)

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";' | 
      sed 's/\x1b\[[0-9;]*m//g'

Tom Hale sugere remover todas as outras seqüências de escape usando em [a-zA-Z]vez da letra mespecífica da seqüência de escape do modo de gráfico (cor). Mas [a-zA-Z]pode ser muito largo e pode remover muito. Michał Faleński e Miguel Mota propõem remover apenas algumas seqüências de escape usando [mGKH]e [mGKF]respectivamente. Britton Kerin indica Kque também deve ser usado além de mremover as cores de gccerro / aviso (não se esqueça de redirecionar gcc 2>&1 | sed...).

sed 's/\x1b\[[0-9;]*m//g'           # Remove color sequences only
sed 's/\x1b\[[0-9;]*[a-zA-Z]//g'    # Remove all escape sequences
sed 's/\x1b\[[0-9;]*[mGKH]//g'      # Remove color and move sequences
sed 's/\x1b\[[0-9;]*[mGKF]//g'      # Remove color and move sequences
Last escape
sequence
character   Purpose
---------   -------------------------------
m           Graphics Rendition Mode (including Color)
G           Horizontal cursor move
K           Horizontal deletion
H           New cursor position
F           Move cursor to previous n lines

Usando perl

A versão do sedinstalada em alguns sistemas operacionais pode ser limitada (por exemplo, macOS). O comando perltem a vantagem de ser geralmente mais fácil de instalar / atualizar em mais sistemas operacionais. Adam Katz sugere usar \e(o mesmo que \x1b) no PCRE .

Escolha seu regex dependendo de quantos comandos você deseja filtrar:

perl -pe 's/\e\[[0-9;]*m//g'          # Remove colors only
perl -pe 's/\e\[[0-9;]*[mG]//g'
perl -pe 's/\e\[[0-9;]*[mGKH]//g'
perl -pe 's/\e\[[0-9;]*[a-zA-Z]//g'
perl -pe 's/\e\[[0-9;]*m(?:\e\[K)?//g' # Adam Katz's trick

Exemplo com a linha de comando do OP:

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";' \
      | perl -pe 's/\e\[[0-9;]*m//g'

Uso

Conforme apontado pelo comentário de Stuart Cardall , essa sedlinha de comando é usada pelo projeto Ultimate Nginx Bad Bot (1000 estrelas) para limpar o relatório de email ;-)


2
Obrigado pelo sedcomando e a explicação. :)
Redsandro

2
Alguns códigos de cores (por exemplo, terminal Linux) contêm um prefixo, por exemplo, 1;31mé melhor adicionar ;ao seu regex: cat colored.log | sed -r 's/\x1b\[[0-9;]*m//g'ou eles não serão removidos.
Redsandro

1
isso é ótimo, usei no github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/blob/… para limpar o relatório de email.
Stuart Cardall

2
Lembre-se de que a versão OSX de sednão funcionou com o exemplo mostrado, mas a gsedversão funciona.
slm

2
Mais contexto para o comentário da slm sobre o OSX sed: ele não suporta caracteres de controle como \ x1b. Por exemplo, stackoverflow.com/a/14881851/93345 . Você pode obter o comando gsed via brew install gnu-sed.
steamer25


10

O que é exibido como não^[ é e ; é o caractere ASCII , produzido por ou (a notação significa a tecla Ctrl). ^[ESCEscCtrl[^

ESCé 0x1B hexadecimal ou 033 octal, então você deve usar \x1Bou \033em suas expressões regulares:

perl -pe 's/\033\[37m//g; s/\033[0m//g'

perl -pe 's/\033\[\d*(;\d*)*m//g'

6

Se você preferir algo simples, poderá usar o módulo strip-ansi (é necessário o Node.js. ):

$ npm install --global strip-ansi-cli

Em seguida, use-o assim:

$ strip-ansi < colors.o

Ou apenas passe uma string:

$ strip-ansi '^[[37mABC^[[0m'

Este é um uso inútil de cat( UUOC ) - deve ser possível fazer strip-ansi colors.oou pelo menos strip-ansi < colors.o.
1175 Scott Scott

1
@ Scott Certamente, você também pode fazer isso strip-ansi < colors.o, mas por experiência as pessoas estão mais familiarizadas com a tubulação. Eu atualizei a resposta.
Sindre Sorhus 11/02

boa solução simples
Penghe Geng


3

Eu acredito que esta é uma remoção autorizada de todas as seqüências de escape ANSI :

perl -pe '
  s/\e\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]//g;
  s/\e[PX^_].*?\e\\//g;
  s/\e\][^\a]*(?:\a|\e\\)//g;
  s/\e[\[\]A-Z\\^_@]//g;'

(Observe que o perl, como muitos outros idiomas (mas não o sed), aceita \ecomo caractere de escape Esc, \x1bou \033por código, mostrado nos terminais como ^[. Estou usando-o aqui porque parece mais intuitivo.)

Este comando perl, que você pode executar todos em uma linha, se preferir, possui quatro substituições:

A primeira ocorre após as seqüências CSI (sequências de códigos de escape que começam com o "Control Sequence Introducer" de Esc[, que abrange muito mais do que as sequências Select Graphic Rendition que compõem os códigos de cores e outras decorações de texto).

A segunda substituição remove as seqüências restantes que envolvem caracteres finais e termina com ST (o terminador de seqüência de caracteres Esc\). A terceira substituição é a mesma coisa, mas também permite Operacional comando do sistema seqüências para acabar com um BEL ( \x07, \007, muitas vezes \a).

A quarta substituição remove as fugas restantes.

Considere também remover outros caracteres ASCII de largura zero, como BEL e outros caracteres de controle C0 e C1 mais obscuros . Eu tenho usado s/[\x00-\x1f\x7f-\x9f\xad]+//g, que também inclui Excluir e Soft Hífen . Isso exclui os caracteres de largura zero codificados mais altos do Unicode, mas acredito que seja exaustivo para o ASCII (Unicode \x00- \xff). Se você fizer isso, remova esses últimos, pois eles podem estar envolvidos em seqüências mais longas.


2

A pergunta "respondida" não funcionou para mim, então criei esse regex para remover as seqüências de escape produzidas pelo módulo Perl Term :: ANSIColor.

cat colors.o | perl -pe 's/\x1b\[[^m]+m//g;

O regex do Grawity deve funcionar bem, mas o uso de + parece funcionar também.


4
(1) Como assim The "answered" question? Você quer dizer a resposta aceita? (2) Este comando não funciona - nem mesmo é executado - porque possui uma cotação inigualável (desequilibrada). (3) Este é um uso inútil de cat( UUOC ) - deve ser possível . (4) Quem nunca disse algo sobre os códigos estarem em um arquivo? perl -pe command colors.o.o
1175 Scott Scott

1

"tput sgr0" deixou esse caractere de controle ^ (B ^ [
Aqui está uma versão modificada para cuidar disso.

perl -pe 's/\e[\[\(][0-9;]*[mGKFB]//g' logfile.log

Obrigado por isso ... isso funcionou para eu me livrar daquilo tput sgr0que as outras soluções nunca parecem capazes de se livrar.
TxAG98 26/07

0

Eu tive um problema semelhante com a remoção de caracteres adicionados ao coletar saída superior interativa via massa e isso ajudou:

cat putty1.log | perl -pe 's/\x1b.*?[mGKH]//g'

3
Este é um uso inútil de cat( UUOC ) - deve ser possível . perl -pe command putty1.log
1175 Scott Scott

0

Foi isso que funcionou para mim (testado no Mac OS X)

perl -pe 's/\[[0-9;]*[mGKF]//g'
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.