Falha na saída de cor da festança


8

É um problema de sed ou eco? O que estou fazendo de 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 destaque em negrito é o que era esperado.

Respostas:


11

sednão trata \ecomo uma sequência de escape. Com o GNU sed, e a maioria das outras implementações sed lá fora, \eem um stexto de substituição apenas significa e. Os escapes única barra invertida você pode usar portably no stexto de substituição são \\para significar uma barra invertida, \&para significar uma literal &, \/(onde /é o caractere delimitador) para um literal /, e \1através \9de referências anteriores. O GNU sed e o BusyBox (mas não o OpenBSD sed) adicionam \numa 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 seqüências de escape reconhecidas pela $'…'construção.

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

6

Existem dois problemas no seu echocomando.

Expandi as variáveis ​​por questões de 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 a magia sed e a magia shell. 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 escapando?

$ 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. Não tenho idéia do por que precisamos de três barras invertidas, isso é uma mágica sedutora estranha.

Segundo problema: o echo -eé inútil. -epermite a interpretação de escapes de barra invertida, mas tudo o que echo -eé preciso interpretar é "test TEST test". As fugas de barra invertida são provenientes do sed, que não se importa com elas e as imprime em bruto.

O que você quer é isso:

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

com TEST 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")

Entre, echo -e "${BWhite}AAAA${ColorOff}"mostra `\ AAAA`. É uma pena, porque eu preciso manter regular_color_constants e SED_color_constants. Na verdade, eu quero ter apenas regular_color_constants e corrigir as opções echo e sed para obter o que quero.
ДМИТРИЙ МАЛИКОВ

Essa solução é bastante frágil (e se $stringcontém uma barra invertida?) E é um pouco mais complicada do que o necessário. Para entender as citações, leve as coisas uma por vez. Por exemplo, as três barras invertidas não são absolutamente mágicas: primeiro, há aspas duplas e "\\\e"é a sequência de dois caracteres \e; então sed entende \ecomo "o personagem eliteralmente".
Gilles 'SO- stop be evil' (
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.