Il cambio del colore avviene tramite sequenze di escape incorporate nel testo. Invariabilmente, i programmi emettono sequenze di escape ANSI , perché questo è ciò che praticamente supporta tutti i terminali al giorno d'oggi.
La sequenza di escape per cambiare il colore di primo piano in rosso è \e[31m, dove \edesigna un carattere di escape (033 ottale, 1b esadecimale, noto anche come ESC ^[e varie altre designazioni). I numeri nell'intervallo 30–39 impostano il colore di primo piano; altri numeri impostano attributi diversi. \e[0mripristina tutti gli attributi al loro valore predefinito. Esegui cat -vper verificare ciò che il programma stampa, potrebbe utilizzare alcune varianti come \e[0;31mripristinare prima tutti gli attributi o \e[3;31anche attivare il corsivo (che molti terminali non supportano).
In ksh, bash o zsh, è possibile utilizzare $'…'per abilitare le escape di barra rovesciata all'interno delle virgolette, che consente di digitare $'\e'per ottenere un carattere di escape. Nota che dovrai quindi raddoppiare qualsiasi barra rovesciata a cui vuoi passare grep. In /bin/sh, puoi usare "$(printf \\e)"o digitare un carattere di escape letterale.
Con l' grep -oopzione GNU , il seguente frammento filtra il testo rosso, supponendo che inizi con la sequenza di escape \e[31m, termina con una \e[0mo \e[30msulla stessa riga e non contenga alcuna sequenza di escape incorporata.
grep -Eo $'\e\\[31m[^\e]*\e\\[[03]?m'
Il awkframmento seguente estrae il testo rosso, anche quando è multilinea.
awk -v RS='\033' '
match($0, /^\[[0-9;]*m/) {
color = ";" substr($0, 2, RLENGTH-2) ";";
$0 = substr($0, RLENGTH+1);
gsub(/(^|;)0*[^03;][0-9]*($|;)/, ";", color);
red = (color ~ /1;*$/)
}
red'
Ecco una variante che conserva i comandi di cambio colore, che potrebbe essere utile se stai filtrando più colori (qui rosso e magenta).
awk -v RS='\033' '
match($0, /^\[[0-9;]*m/) {
color = ";" substr($0, 2, RLENGTH-2) ";";
printf "\033%s", substr($0, 1, RLENGTH);
$0 = substr($0, RLENGTH+1);
gsub(/(^|;)0*[^03;][0-9]*($|;)/, ";", color);
desired = (color ~ /[15];*$/)
}
desired'
>&1? Voglio dire, le cose rosse non vanno via se tu2>/dev/null, giusto?