A saída de cor do Bash falha

8

É sed ou problema de eco? O que estou fazendo errado?

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

TESTE com realce em negrito é o esperado.

    
por ДМИТРИЙ МАЛИКОВ 23.08.2011 / 13:30

2 respostas

11

sed não trata \e como uma sequência de escape. Com o GNU sed e a maioria das outras implementações de sed lá fora, \e em um texto de substituição s significa apenas e . As únicas escapes de barra invertida que podem ser portadas em s texto de substituição são \ para significar uma barra invertida, \& significa literal & , \/ (onde / é o caractere delimitador) para um literal / e a para referências anteriores. O GNU sed e o BusyBox (mas não, por exemplo, o OpenBSD sed) adicionam \n para uma nova linha. Assim, a saída do seu comando sed tem um literal e .

No bash, você pode facilmente colocar um caractere de escape literal em suas variáveis desde o início. \e é uma das sequências de escape reconhecidas pela construção $'…' .

ColorOff=$'\e[0m'       # Text Reset
BWhite=$'\e[1;37m'      # Bold White
    
por 24.08.2011 / 00:24
6

Existem dois problemas no seu comando echo .

Eu expandi as variáveis para brevidade.

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

Primeiro problema: as barras invertidas são perdidas em algum lugar entre magia sed e magia de conchas. Você tem que escapar deles.

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

Ainda não funciona. Talvez mais fugindo?

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

Finalmente, as barras invertidas estão chegando. Eu não tenho ideia de por que precisamos de três barras invertidas, isso é alguma mágica estranha.

Segundo problema: o echo -e é inútil. -e permite a interpretação de escapes de barra invertida, mas todos os echo -e que conseguem interpretar são "test TEST test" . As fugas de barra invertida são provenientes de sed, que não se preocupam com elas e as imprime cru.

O que você quer é isto:

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

com teste em negrito na saída.

Aqui está o script completo com as alterações:

#!/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 23.08.2011 / 15:31