L'output del colore Bash non riesce


8

È un problema di sed o eco? Cosa sto facendo di sbagliato?

$> cat ~/bin/color_test.sh 
#!/bin/bash

ColorOff='\e[0m'       # Text Reset
BWhite='\e[1;37m'      # Bold White

string="test TEST test"
echo -e "$string" | sed -e "s/TEST/${BWhite}TEST${ColorOff}/g"

$> ~/bin/color_test.sh 
test e[1;37mTESTe[0m test

TEST con evidenziazione in grassetto è quello che ci si aspettava.

Risposte:


11

sednon considera \euna sequenza di escape. Con GNU sed e la maggior parte delle altre implementazioni sed là fuori, \ein un stesto sostitutivo significa solo e. Le fughe solo backslash è possibile utilizzare portabile nel stesto di sostituzione sono \\a significare un backslash, \&a significare un letterale &, \/(dove /è il carattere delimitatore) per un letterale /, e \1attraverso \9per backreference. GNU sed e BusyBox (ma non ad esempio OpenBSD sed) si aggiungono \nper una nuova riga. Quindi l'output del tuo comando sed ha un valore letterale e.

In bash, puoi facilmente inserire un carattere letterale di escape nelle tue variabili dall'inizio. \eè una delle sequenze di escape riconosciute dal $'…'costrutto.

ColorOff=$'\e[0m'       # Text Reset
BWhite=$'\e[1;37m'      # Bold White

6

Ci sono due problemi nel tuo echocomando.

Ho ampliato le variabili per brevità.

$ echo -e "test TEST test" | sed -e "s/TEST/\e[1;37mTEST\e[0m/g"
test e[1;37mTESTe[0m test

Primo problema: le barre rovesciate si perdono da qualche parte tra magia sed e magia shell. Devi scappare da loro.

$ echo -e "test TEST test" | sed -e "s/TEST/\\e[1;37mTEST\\e[0m/g"
test e[1;37mTESTe[0m test

Non funziona ancora. Forse più in fuga?

$ echo -e "test TEST test" | sed -e "s/TEST/\\\e[1;37mTEST\\\e[0m/g"
test \e[1;37mTEST\e[0m test

Finalmente stanno arrivando le barre rovesciate. Non ho idea del perché abbiamo bisogno di tre barre rovesciate, questa è una strana magia sed.

Secondo problema: echo -eè inutile. -eabilita l'interpretazione delle fughe di backslash, ma tutto ciò che echo -eviene interpretato è "test TEST test". Le fughe di backslash provengono da sed, a cui non importa di loro e le stampa crude.

Quello che vuoi è questo:

$ echo -e $(echo "test TEST test" | sed -e "s/TEST/\\\e[1;37mTEST\\\e[0m/g")
test TEST test

con grassetto TEST in uscita.

Ecco lo script completo con le modifiche:

#!/bin/bash

ColorOff='\\\e[0m'       # Text Reset
BWhite='\\\e[1;37m'      # Bold White

string="test TEST test"
echo -e $(echo "$string" | sed -e "s/TEST/${BWhite}TEST${ColorOff}/g")

A proposito, echo -e "${BWhite}AAAA${ColorOff}"mostra `\ AAAA`. È un peccato, perché ho bisogno di mantenere regular_color_constants e SED_color_constants. In realtà, voglio avere solo regular_color_constants e correggere le opzioni echo e sed per ottenere quello che voglio.
ДМИТРИЙ МАЛИКОВ,

Questa soluzione è piuttosto fragile (e se $stringcontiene una barra rovesciata?) Ed è un po 'più complicata del necessario. Per capire la citazione, prendi le cose una alla volta. Ad esempio le tre barre rovesciate non sono affatto magiche: prima ci sono doppie virgolette, ed "\\\e"è la stringa di due caratteri \e; allora sed capisce \ecome "il personaggio eletteralmente".
Gilles 'SO- smetti di essere malvagio' il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.