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 \e
designa 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[0m
ripristina tutti gli attributi al loro valore predefinito. Esegui cat -v
per verificare ciò che il programma stampa, potrebbe utilizzare alcune varianti come \e[0;31m
ripristinare prima tutti gli attributi o \e[3;31
anche 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 -o
opzione GNU , il seguente frammento filtra il testo rosso, supponendo che inizi con la sequenza di escape \e[31m
, termina con una \e[0m
o \e[30m
sulla stessa riga e non contenga alcuna sequenza di escape incorporata.
grep -Eo $'\e\\[31m[^\e]*\e\\[[03]?m'
Il awk
frammento 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?