238 votes

Suppression des couleurs de la sortie

J'ai un script qui produit une sortie avec des couleurs et j'ai besoin de supprimer les codes ANSI.

#!/bin/bash

exec > >(tee log)   # redirect the output to a file but keep it on stdout
exec 2>&1

./somescript

Le résultat est (dans le fichier journal) :

java (pid  12321) is running...@[60G[@[0;32m  OK  @[0;39m]

Je ne savais pas comment mettre le caractère ESC ici, alors j'ai mis @ à sa place.

J'ai changé le script en :

#!/bin/bash

exec > >(tee log)   # redirect the output to a file but keep it on stdout
exec 2>&1

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

Mais maintenant il me donne (dans le fichier journal) :

java (pid  12321) is running...@[60G[  OK  ]

Comment puis-je également supprimer ce @[60G ?

Peut-être y a-t-il un moyen de désactiver complètement la coloration pour l'ensemble du script ?

4voto

Maxxim Points 3

Voici une solution purement Bash.

Enregistrer sous strip-escape-codes.sh rendez-le exécutable, puis exécutez <command-producing-colorful-output> | ./strip-escape-codes.sh .

Notez que cela dépouille todo Codes d'échappement/séquences ANSI. Si vous souhaitez uniquement dépouiller les couleurs, remplacez [a-zA-Z] avec "m" .

Bash >= 4.0 :

#!/usr/bin/env bash

# Strip ANSI escape codes/sequences [$1: input string, $2: target variable]
function strip_escape_codes() {
    local _input="$1" _i _char _escape=0
    local -n _output="$2"; _output=""
    for (( _i=0; _i < ${#_input}; _i++ )); do
        _char="${_input:_i:1}"
        if (( ${_escape} == 1 )); then
            if [[ "${_char}" == [a-zA-Z] ]]; then
                _escape=0
            fi
            continue
        fi
        if [[ "${_char}" == $'\e' ]]; then
            _escape=1
            continue
        fi
        _output+="${_char}"
    done
}

while read -r line; do
    strip_escape_codes "${line}" line_stripped
    echo "${line_stripped}"
done

Bash < 4.0 :

#!/usr/bin/env bash

# Strip ANSI escape codes/sequences [$1: input string, $2: target variable]
function strip_escape_codes() {
    local input="${1//\"/\\\"}" output="" i char escape=0
    for (( i=0; i < ${#input}; ++i )); do         # process all characters of input string
        char="${input:i:1}"                       # get current character from input string
        if (( ${escape} == 1 )); then             # if we're currently within an escape sequence, check if
            if [[ "${char}" == [a-zA-Z] ]]; then  # end is reached, i.e. if current character is a letter
                escape=0                          # end reached, we're no longer within an escape sequence
            fi
            continue                              # skip current character, i.e. do not add to ouput
        fi
        if [[ "${char}" == $'\e' ]]; then         # if current character is '\e', we've reached the start
            escape=1                              # of an escape sequence -> set flag
            continue                              # skip current character, i.e. do not add to ouput
        fi
        output+="${char}"                         # add current character to output
    done
    eval "$2=\"${output}\""                       # assign output to target variable
}

while read -r line; do
    strip_escape_codes "${line}" line_stripped
    echo "${line_stripped}"
done

3voto

Dale_Reagan Points 149

Hmm, je ne suis pas sûr que cela vous convienne, mais "tr" permet de supprimer les données. codes de contrôle - essayez :

./somescript | tr -d '[:cntrl:]'

3voto

zstolar Points 8

La solution de @jeff-bowman m'a aidé à me débarrasser de CERTAINS des codes de couleur. J'ai ajouté une autre petite portion à la regex afin d'en supprimer un peu plus :

sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" # Original. Removed Red ([31;40m[1m[error][0m)
sed -r "s/\x1B\[([0-9];)?([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" # With an addition, removed yellow and green ([1;33;40m[1m[warning][0m and [1;32;40m[1m[ok][0m)
                ^^^^^^^^^
                remove Yellow and Green (and maybe more colors)

3voto

A.B Points 647

L'idée controversée serait de reconfigurer les paramètres du terminal pour cet environnement de processus afin de faire savoir au processus que le terminal ne supporte pas les couleurs.

Quelque chose comme TERM=xterm-mono ./somescript me vient à l'esprit. YMMV avec votre OS spécifique et la capacité de votre script à comprendre les paramètres de couleur du terminal.

2voto

user3387223 Points 124

J'ai eu quelques problèmes avec la sortie colorée que les autres solutions ici ne traitaient pas correctement, alors j'ai construit ce one liner perl. Il recherche les échappements \e suivi d'une parenthèse ouvrante \[ suivi d'un ou plusieurs codes de couleur \d+ séparés par des points-virgules, se terminant par m .

perl -ple 's/\e\[\d+(;\d+)*m//g'

Cela semble fonctionner très bien pour la sortie colorée du compilateur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X