web-dev-qa-db-fra.com

Suppression des codes de couleur ANSI du flux de texte

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) indique ce qui suit:

^[[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'
66
user001

Les caractères ^[[37m et ^[[0m font partie des séquences d'échappement ANSI (codes CSI) .
Voir aussi les spécifications complètes .

Utiliser sed

sed 's/\x1b\[[0-9;]*m//g'
  • \x1b est le caractère spécial d'échappement (identique à \x1B ou \033)
  • \[ est le deuxième caractère de la séquence d'échappement
  • [0-9;]* est la valeur de la couleur
  • m est le dernier caractère de la séquence d'échappement

Exemple avec la ligne de commande de OP: (OP = O riginal P oster)

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] à la place de la lettre m spécifique à la séquence d'échappement couleur. Mais [a-zA-Z] est peut-être trop large et pourrait en supprimer trop. Michał Faleński et Miguel Mota propose de supprimer uniquement certaines séquences d'échappement à l'aide de [mGKH] et [mGKF] respectivement.

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           Color
G           Horizontal cursor move
K           Horizontal deletion
H           New cursor position
F           Move cursor to previous n lines

Utiliser Perl

La version de sed installée sur certains systèmes d'exploitation peut être limitée (MacOS X, par exemple). La commande Perl présente l'avantage d'être souvent plus facile à installer/mettre à jour sur plusieurs systèmes d'exploitation.

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

Perl -pe 's/\x1b\[[0-9;]*m//g'        # Remove colors only
Perl -pe 's/\x1b\[[0-9;]*[mG]//g'
Perl -pe 's/\x1b\[[0-9;]*[mGKH]//g'
Perl -pe 's/\x1b\[[0-9;]*[a-zA-Z]//g'

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/\x1b\[[0-9;]*m//g'

Usage

Comme l'a souligné le commentaire de Stuart Cardall , cette astuce est utilisée par le projet Ultimate Nginx Bad Bot (presque 1000 étoiles) pour nettoyer le rapport par email ;-)

82
olibre

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

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

18
user204331

Ce qui est affiché comme ^[ est non^ et [; il s'agit du caractère ASCII ESCname__, produit par Esc ou Ctrl[ (la notation ^ signifie la touche Ctrl).

ESCest 0x1B hexadécimal ou 033 octal. Vous devez donc utiliser \x1B ou \033 dans vos expressions rationnelles:

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

Perl -pe 's/\033\[\d*(;\d*)*m//g'
9
grawity

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

$ 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'
4
Sindre Sorhus

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.

2
castl3bravo

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"
2
Tom Hale

Je crois que ceci est une suppression faisant autorité de tous 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;'

(Veuillez noter que Perl, comme beaucoup d'autres langues (mais pas sed), accepte \e en tant que caractère d'échappement. Esc, \x1b ou \033 par code, indiqué dans les terminaux par ^[. Je l'utilise ici parce que cela semble plus intuitif.)

Cette commande Perl, que vous pouvez exécuter sur une seule ligne si vous préférez, comporte deux remplacements. Le premier va après les séquences CSI (séquences de code d’échappement commençant par le "Contrôleur d’introduction de séquence" de Esc[, qui couvre beaucoup plus que le = Sélectionnez les séquences de rendu graphique qui composent les codes de couleur et autres décorations de texte).

Le second remplacement supprime les séquences restantes impliquant des caractères de fin et se termine par ST (le terminateur de chaîne, Esc\). Le troisième remplacement est identique, mais permet également de terminer les séquences de commande du système d'exploitation par un BEL (\x07, souvent \a).

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

Pensez également à supprimer les autres caractères ASCII de largeur nulle, tels que BEL et d'autres caractères plus obscurs caractères de contrôle C0 et C1 . J'utilise [\x00-\x1f\x7f-\x9f\xad], qui inclut également Supprimer et trait d'union . Cela exclut les caractères de largeur nulle codés plus élevés par Unicode, mais je crois que cela 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.

0
Adam Katz

J'ai eu un problème similaire avec la suppression des caractères ajoutés lors de la collecte des sorties interactives via PuTTY, ce qui a aidé:

cat PuTTY1.log | Perl -pe 's/\x1b.*?[mGKH]//g'
0
Michał Faleński

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

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