La salida de color de falla falla


8

¿Es un problema de sed o eco? ¿Qué estoy haciendo mal?

$> 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

PRUEBA con resaltado en negrita es lo que se esperaba.

Respuestas:


11

sedno trata \ecomo una secuencia de escape. Con GNU sed, y la mayoría de las otras implementaciones de sed existentes, \een un stexto de reemplazo solo significa e. Los escapes de barra invertida solamente se pueden utilizar de forma portátil en el stexto de reemplazo son \\en el sentido de una barra invertida, \&en el sentido literal &, \/(donde /es el carácter delimitador) para un literal /, y \1por medio \9de referencias hacia atrás. GNU sed y BusyBox (pero no, por ejemplo, OpenBSD sed) se agregan \npara una nueva línea. Por lo tanto, la salida de su comando sed tiene un literal e.

En bash, puede poner fácilmente un carácter de escape literal en sus variables desde el principio. \ees una de las secuencias de escape reconocidas por la $'…'construcción.

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

6

Hay dos problemas en su echocomando.

Expandí las variables por brevedad.

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

Primer problema: las barras invertidas se pierden en algún lugar entre la magia sed y la magia de concha. Tienes que escapar de ellos.

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

Aún no funciona. ¿Quizás más escapando?

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

Finalmente, las barras invertidas están llegando. No tengo idea de por qué necesitamos tres barras invertidas, esa es una extraña magia sed.

Segundo problema: el no echo -etiene sentido. -epermite la interpretación de los escapes de barra invertida, pero todo lo que echo -ese puede interpretar es "test TEST test". Los escapes de la barra invertida provienen de sed, que no se preocupa por ellos y los imprime sin procesar.

Lo que quieres es esto:

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

con PRUEBA en negrita en la salida.

Aquí está el script completo con los cambios:

#!/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")

Por cierto, echo -e "${BWhite}AAAA${ColorOff}"muestra `\ AAAA`. Es una pena, porque necesito mantener regular_color_constants y SED_color_constants. En realidad, quiero tener solo regular_color_constants, y arreglar las opciones echo y sed para obtener lo que quiero.
ДМИТРИЙ МАЛИКОВ

Esa solución es bastante frágil (¿y si $stringcontiene una barra invertida?) Y es bastante más complicada de lo necesario. Para entender las citas, tome las cosas de una en una. Por ejemplo, las tres barras invertidas no son magia mágica: primero hay comillas dobles, y "\\\e"es la cadena de dos caracteres \e; entonces sed entiende \ecomo "el personaje eliteralmente".
Gilles 'SO- deja de ser malvado'
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.