Suppression des codes de couleur ANSI du flux de texte

73

Examiner les résultats de

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

dans un éditeur de texte (par exemple, vi) affiche les éléments suivants:

^[[37mABC
^[[0m

Comment supprimer les codes de couleur ANSI du fichier de sortie? Je suppose que le meilleur moyen serait de diriger la sortie via un éditeur de flux de toutes sortes.

Ce qui suit ne fonctionne pas

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";' | perl -pe 's/\^\[\[37m//g' | perl -pe 's/\^\[\[0m//g'
utilisateur001
la source
Ce n'est pas une réponse à la question, mais vous pouvez également diriger la sortie vers moreou pour less -Rinterpréter les codes d'échappement sous forme de couleur au lieu d'un éditeur de texte.
Terdon le

Réponses:

98

Les caractères ^[[37met ^[[0mfont partie des séquences d'échappement ANSI (codes CSI) . Voir aussi ces spécifications .

Utiliser GNU sed

sed 's/\x1b\[[0-9;]*m//g'
  • \x1b(ou \x1B) est le caractère spécial d' échappement
    ( sedne prend pas en charge les alternatives \eet \033)
  • \[ est le deuxième caractère de la séquence d'échappement
  • [0-9;]* est la valeur de couleur regex
  • m est le dernier caractère de la séquence d'échappement

Sur macOS, la sedcommande par défaut ne prend pas en charge les caractères spéciaux tels \eque ceux signalés par slm et steamer25 dans les commentaires. Utilisez plutôt gsedque vous pouvez installer en utilisant brew install gnu-sed.

Exemple avec la ligne de commande de OP:   (OP signifie affiche originale)

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

Tom Hale suggère de supprimer toutes les autres séquences d'échappement en utilisant [a-zA-Z]au lieu de la lettre mpropre à la séquence d'échappement en mode graphique (couleur). Mais [a-zA-Z]peut être trop large et pourrait enlever trop. Michał Faleński et Miguel Mota proposent de ne supprimer que certaines séquences d'échappement avec [mGKH]et [mGKF]respectivement. Britton Kerin indique qu'il Kfaut également utiliser en plus de msupprimer les couleurs d' gccerreur / avertissement (n'oubliez pas de rediriger 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

En utilisant perl

La version de sedinstallée sur certains systèmes d'exploitation peut être limitée (par exemple, macOS). La commande perla l'avantage d'être généralement plus facile à installer / mettre à jour sur plusieurs systèmes d'exploitation. Adam Katz suggère d'utiliser \e(idem \x1b) dans PCRE .

Choisissez votre regex en fonction du nombre de commandes que vous souhaitez filtrer:

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

Exemple avec la ligne de commande de OP:

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

Usage

Comme le souligne le commentaire de Stuart Cardall , cette sedligne de commande est utilisée par le projet Ultimate Nginx Bad Bot (1 000 étoiles) pour nettoyer le rapport de courrier électronique ;-)

olibre
la source
2
Merci pour la sedcommande et l'explication. :)
Redsandro
2
Certains codes de couleur (par exemple, les terminaux Linux) contiennent un préfixe, par exemple, 1;31mil est préférable d’ajouter ;à votre expression rationnelle: sinon cat colored.log | sed -r 's/\x1b\[[0-9;]*m//g'ils ne seront pas supprimés.
Redsandro
1
c'est génial de l'utiliser dans github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/blob/… pour nettoyer le rapport par courrier électronique.
Stuart Cardall
2
Gardez à l'esprit que la version OSX de sedne fonctionnait pas avec l'exemple présenté, mais cette gsedversion fonctionne.
Slm
2
Plus de contexte pour le commentaire de slm sur OSX sed: il ne supporte pas les caractères de contrôle comme \ x1b. Par exemple, stackoverflow.com/a/14881851/93345 . Vous pouvez obtenir la commande gsed via brew install gnu-sed.
steamer25
21

J'ai découvert un meilleur dissolvant de séquence d'échappement. Vérifie ça:

perl -pe 's/\x1b\[[0-9;]*[mG]//g'

utilisateur204331
la source
2
Quelle est l’amélioration par rapport à la réponse acceptée ( superuser.com/a/380778/46794 )?
Blaisorblade
4
@Blaisorblade Cela fonctionne sur OS X, alors que ce sed -rn'est pas le cas.
BVengerov
10

Ce qui est affiché comme ^[est pas ^ et [; c'est le ESCcaractère ASCII , produit par Escou Ctrl[(la ^notation signifie la touche Ctrl).

ESCest 0x1B hexadécimal ou 033 octal, vous devez donc utiliser \x1Bou \033dans vos regex:

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

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

Si vous préférez quelque chose de simple, vous pouvez utiliser le module strip-ansi ( Node.js requis):

$ npm install --global strip-ansi-cli

Ensuite, utilisez-le comme ceci:

$ strip-ansi < colors.o

Ou simplement passer une chaîne:

$ strip-ansi '^[[37mABC^[[0m'
Sindre Sorhus
la source
Ceci est une utilisation inutile de cat( UUOC ) - il devrait être possible de le faire strip-ansi colors.oou du moins strip-ansi < colors.o.
Scott
1
@ Scott Bien sûr, vous pouvez également le faire strip-ansi < colors.o, mais par expérience, les gens sont plus familiarisés avec la tuyauterie. J'ai mis à jour la réponse.
Sindre Sorhus
bonne solution simple
Penghe Geng
3

commandlinefu donne cette réponse qui supprime les couleurs ANSI ainsi que les commandes de mouvement:

sed "s,\x1B\[[0-9;]*[a-zA-Z],,g"

Pour seulement des couleurs, vous voulez:

 sed "s,\x1B\[[0-9;]*m,,g"
Tom Hale
la source
3

Je crois que ceci est une suppression faisant autorité de toutes les séquences d'échappement 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;'

(S'il vous plaît noter qu'il perl, comme beaucoup d' autres langues (mais pas sed), accepte \ecomme caractère d'échappement Esc, \x1bou \033par code, montré dans les terminaux comme ^[. Je l' utilise ici car il semble plus intuitive.)

Cette commande perl, que vous pouvez exécuter sur une seule ligne si vous préférez, comporte quatre remplacements:

Le premier va après les séquences CSI (les séquences de code d’échappement commençant par le "Contrôleur de séquence" de Esc[, qui couvre bien plus que les séquences de sélection de rendu graphique qui composent les codes de couleur et autres décorations de texte).

Le deuxième remplacement supprime les séquences restantes qui impliquent des caractères de fin et se terminent par ST (le terminateur de chaîne, Esc\). Le troisième remplacement est la même chose , mais permet également le système d' exploitation commande des séquences pour mettre fin avec un BEL ( \x07, \007souvent \a).

Le quatrième remplacement supprime les échappées restantes.

Pensez également à supprimer d'autres caractères ASCII de largeur nulle, tels que BEL et d'autres caractères de contrôle C0 et C1 plus obscurs . J'ai utilisé s/[\x00-\x1f\x7f-\x9f\xad]+//g, qui comprend également Supprimer et Soft Hyphen . Ceci exclut les caractères de largeur nulle codés plus élevés par Unicode, mais je crois que c'est exhaustif pour ASCII (Unicode \x00- \xff). Si vous faites cela, supprimez ces dernières car elles peuvent être impliquées dans des séquences plus longues.

Adam Katz
la source
2

La question "Répondu" ne fonctionnant pas pour moi, j'ai donc créé cette expression rationnelle à la place pour supprimer les séquences d'échappement générées par le module perl Term :: ANSIColor.

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

Les expressions rationnelles de Grawity devraient fonctionner correctement, mais l'utilisation de + semble également fonctionner correctement.

castl3bravo
la source
4
(1) Qu'entendez-vous par The "answered" question? Voulez-vous dire la réponse acceptée? (2) Cette commande ne fonctionne pas - elle ne s’exécute même pas - car elle a une citation non équilibrée (non équilibrée). (3) C’est une utilisation inutile de cat( UUOC ) - il devrait être possible de le faire . (4) Qui a jamais dit quoi que ce soit à propos des codes dans un fichier? perl -pe command colors.o.o
Scott
1

"tput sgr0" a quitté ce caractère de contrôle ^ (B ^ [
Voici une version modifiée pour s'en occuper.

perl -pe 's/\e[\[\(][0-9;]*[mGKFB]//g' logfile.log
GustafAnkarloo
la source
Merci pour cela ... cela a fonctionné pour moi de me débarrasser de ce tput sgr0que les autres solutions ne semblent jamais pouvoir se débarrasser.
TxAG98 le
0

J'ai eu un problème similaire avec la suppression des caractères ajoutés lors de la collecte de la sortie interactive supérieure via mastic, ce qui a aidé:

cat putty1.log | perl -pe 's/\x1b.*?[mGKH]//g'
Michał Faleński
la source
3
C'est une utilisation inutile de cat( UUOC ) - il devrait être possible de le faire . perl -pe command putty1.log
Scott
0

C'est ce qui a fonctionné pour moi (testé sur Mac OS X)

perl -pe 's/\[[0-9;]*[mGKF]//g'
Miguel Mota
la source