La sortie de couleur basique échoue

8

Est-ce un problème de séduction ou d'écho? Qu'est-ce que je fais 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

TEST avec surlignage en gras est ce qui était attendu.

ДМИТРИЙ МАЛИКОВ
la source

Réponses:

11

sedne traite pas \ecomme une séquence d'échappement. Avec GNU sed, et la plupart des autres implémentations sed, \eun stexte de remplacement signifie simplement e. Les évasions ne backslash que vous pouvez utiliser dans portably stexte de remplacement sont \\signifier une barre oblique inverse, \&pour signifier un littéral &, \/(où /est le caractère delimiter) pour un littéral /, et \1par \9des références arrières. GNU sed et BusyBox (mais pas par exemple OpenBSD sed) ajoute \npour une nouvelle ligne. Ainsi, la sortie de votre commande sed a un littéral e.

En bash, vous pouvez facilement mettre un caractère d'échappement littéral dans vos variables depuis le début. \eest l'une des séquences d'échappement reconnues par la $'…'construction.

ColorOff=$'\e[0m'       # Text Reset
BWhite=$'\e[1;37m'      # Bold White
Gilles 'SO- arrête d'être méchant'
la source
6

Il y a deux problèmes dans votre echocommande.

J'ai développé les variables par souci de concision.

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

Premier problème: les contre-obliques se perdent quelque part entre la magie sed et la magie shell. Vous devez leur échapper.

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

Ça ne marche toujours pas. Peut-être plus échappant?

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

Finalement, les contre-obliques arrivent. Je ne sais pas pourquoi nous avons besoin de trois barres obliques inverses, c'est de la magie sed séduisante.

Deuxième problème: le echo -eest inutile. -epermet d'interpréter les échappements de barre oblique inverse, mais tout ce qui echo -earrive à interpréter est "test TEST test". Les échappements de barre oblique inversée proviennent de sed, qui ne se soucie pas d'eux et les imprime bruts.

Ce que vous voulez c'est:

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

avec un TEST gras en sortie.

Voici le script complet avec les modifications:

#!/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")
lesmana
la source
Btw, echo -e "${BWhite}AAAA${ColorOff}"affiche «\ AAAA». C'est dommage, car je dois garder regular_color_constants et SED_color_constants. En fait, je veux avoir seulement regular_color_constants, et corriger les options echo et sed pour obtenir ce que je veux.
ДМИТРИЙ МАЛИКОВ
Cette solution est plutôt fragile (et si elle $stringcontient une barre oblique inverse) et est un peu plus compliquée que nécessaire. Pour comprendre la citation, prenez les choses une par une. Par exemple, les trois barres obliques inverses ne sont pas du tout de la magie sed: d'abord il y a des guillemets doubles, et "\\\e"c'est la chaîne de deux caractères \e; alors sed comprend \ecomme "le personnage elittéralement".
Gilles 'SO- arrête d'être méchant'