Rimozione dei codici colore ANSI dal flusso di testo


73

Esame dell'output da

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

in un editor di testo (ad es. vi) mostra quanto segue:

^[[37mABC
^[[0m

Come si rimuovono i codici colore ANSI dal file di output? Suppongo che il modo migliore sarebbe quello di convogliare l'output attraverso un editor di stream di sorta.

Quanto segue non funziona

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

Non è una risposta alla domanda, ma puoi anche reindirizzare l'output moreo less -Rche può interpretare i codici di escape come colore anziché come un editor di testo.
terdon,

Risposte:


98

I caratteri ^[[37me ^[[0mfanno parte delle sequenze di escape ANSI (codici CSI) . Vedi anche queste specifiche .

Usando GNU sed

sed 's/\x1b\[[0-9;]*m//g'
  • \x1b(o \x1B) è il carattere speciale di escape
    ( sednon supporta alternative \ee \033)
  • \[ è il secondo carattere della sequenza di escape
  • [0-9;]* è il valore del colore regex
  • m è l'ultimo carattere della sequenza di escape

⚠ Su macOS, il sedcomando predefinito non supporta caratteri speciali \ecome indicato da slm e steamer25 nei commenti. Usa invece gsedche puoi installare usando brew install gnu-sed.

Esempio con la riga di comando di OP:   (OP significa Poster originale)

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

Tom Hale suggerisce di rimuovere tutte le altre sequenze di escape utilizzando al [a-zA-Z]posto della lettera mspecifica della sequenza di escape in modalità grafica (colore). Ma [a-zA-Z]potrebbe essere troppo largo e potrebbe rimuovere troppo. Michał Faleński e Miguel Mota propongono di rimuovere solo alcune sequenze di escape usando [mGKH]e [mGKF]rispettivamente. Britton Kerin indica che Kdeve essere utilizzato anche per mrimuovere i colori da gccerrori / avvisi (non dimenticare di reindirizzare 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

utilizzando perl

La versione sedinstallata su alcuni sistemi operativi potrebbe essere limitata (ad es. MacOS). Il comando perlha il vantaggio di essere generalmente più facile da installare / aggiornare su più sistemi operativi. Adam Katz suggerisce di usare \e(lo stesso di \x1b) in PCRE .

Scegli la tua regex in base a quanti comandi vuoi filtrare:

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

Esempio con la riga di comando di OP:

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

uso

Come sottolineato dal commento di Stuart Cardall , questa sedriga di comando viene utilizzata dal progetto Ultimate Nginx Bad Bot (1000 stelle) per ripulire il rapporto e-mail ;-)


2
Grazie per il sedcomando e la spiegazione. :)
Redsandro,

2
Alcuni codici colore (ad es. Terminale Linux) contengono un prefisso, ad es. 1;31mQuindi meglio aggiungere ;al tuo regex: cat colored.log | sed -r 's/\x1b\[[0-9;]*m//g'altrimenti non verranno rimossi.
Redsandro

1
questo è ottimo usato in github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/blob/… per ripulire il rapporto e-mail.
Stuart Cardall,

2
Tieni presente che la versione OSX di sednon ha funzionato con l'esempio mostrato, gsedtuttavia la versione funziona.
slm

2
Più contesto per il commento di slm su OSX sed: non supporta i caratteri di controllo come \ x1b. Ad esempio, stackoverflow.com/a/14881851/93345 . È possibile ottenere il comando gsed tramite brew install gnu-sed.
steamer25


10

Ciò che viene visualizzato come non lo^[ è e ; è il carattere ASCII , prodotto da o (la notazione significa il tasto Ctrl). ^[ESCEscCtrl[^

ESCè 0x1B esadecimale o 033 ottale, quindi devi usare \x1Bo \033nei tuoi regex:

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

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

6

Se preferisci qualcosa di semplice puoi usare il modulo strip-ansi ( Node.js richiesto):

$ npm install --global strip-ansi-cli

Quindi usalo in questo modo:

$ strip-ansi < colors.o

Oppure passa semplicemente una stringa:

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

Questo è un uso inutile di cat( UUOC ) - dovrebbe essere possibile farlo strip-ansi colors.oo almeno strip-ansi < colors.o.
Scott,

1
@Scott Certo, puoi anche farlo strip-ansi < colors.o, ma per esperienza le persone hanno più familiarità con le tubazioni. Ho aggiornato la risposta.
Sindre Sorhus,

buona soluzione semplice
Penghe Geng


3

Credo che questa sia una rimozione autorevole di tutte le sequenze di 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;'

(Nota che perl, come molte altre lingue (ma non sed), accetta \ecome carattere di escape Esc, \x1bo \033per codice, mostrato nei terminali come ^[. Lo sto usando qui perché sembra più intuitivo.)

Questo comando perl, che puoi eseguire tutto su una riga se preferisci, contiene quattro sostituzioni:

Il primo va dopo sequenze CSI (sequenze di codici di fuga che iniziano con il "controllo di sequenza introduttore" di Esc[, che copre molto di più rispetto alle sequenze Select Graphic Rendition che compongono i codici dei colori e altre decorazioni di testo).

La seconda sostituzione rimuove le sequenze rimanenti che coinvolgono caratteri finali e terminano con ST (String Terminator, Esc\). Il terzo sostituzione è la stessa cosa, ma permette anche Operating System Command sequenze terminano con un BEL ( \x07, \007, spesso \a).

La quarta sostituzione rimuove le fughe rimanenti.

Prendi anche in considerazione la rimozione di altri caratteri ASCII di larghezza zero come BEL e altri caratteri di controllo C0 e C1 più oscuri . Ho usato s/[\x00-\x1f\x7f-\x9f\xad]+//g, che include anche Elimina e trattino morbido . Ciò esclude i caratteri di larghezza zero a codice superiore con codice Unicode, ma credo che sia esaustivo per ASCII (Unicode \x00- \xff). Se lo fai, rimuovi questi ultimi poiché possono essere coinvolti in sequenze più lunghe.


2

La domanda "risposta" non ha funzionato per me, quindi ho creato questa regex invece di rimuovere le sequenze di escape prodotte dal modulo perl Term :: ANSIColor.

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

La regex di Grawity dovrebbe funzionare bene, ma anche l'uso di + sembra funzionare bene.


4
(1) Cosa intendi con The "answered" question? Intendi la risposta accettata? (2) Questo comando non funziona - non esegue nemmeno - perché ha una virgoletta senza pari (sbilanciata). (3) Questo è un uso inutile di cat( UUOC ) - dovrebbe essere possibile farlo . (4) Chi ha mai detto qualcosa sui codici contenuti in un file? perl -pe command colors.o.o
Scott,

1

"tput sgr0" ha lasciato questo carattere di controllo ^ (B ^ [
Ecco una versione modificata per occuparsene.

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

Grazie per questo ... questo ha funzionato per me per sbarazzarmi di quello tput sgr0che le altre soluzioni non sembrano mai essere in grado di sbarazzarsi.
TxAG98,

0

Ho avuto un problema simile con la rimozione dei caratteri aggiunti dalla raccolta dell'output interattivo tramite putty e questo mi ha aiutato:

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

3
Questo è un uso inutile di cat( UUOC ) - dovrebbe essere possibile farlo . perl -pe command putty1.log
Scott,

0

Questo è ciò che ha funzionato per me (testato su Mac OS X)

perl -pe 's/\[[0-9;]*[mGKF]//g'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.