Сбой вывода цвета Bash

8

Это сед или проблема с эхом? Что я делаю не так?

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

Тест с жирным выделением - это то, что ожидалось.

ДМИТРИЙ МАЛИКОВ
источник

Ответы:

11

sedне рассматривается \eкак escape-последовательность. С GNU sed и большинством других реализаций sed \eв sтексте замены просто имеется в виду e. Единственный обратный слэш ускользает вы можете использовать переносимые в sтексте замен являются \\означать обратный косую черту, \&означают буквальный &, \/(где /это символ разделителя) для буквального /, и \1через \9для обратных ссылок. GNU sed и BusyBox (но не, например, OpenBSD sed) добавляет \nновую строку. Таким образом, вывод вашей команды sed имеет литерал e.

В bash вы можете легко вставить буквальный escape-символ в ваши переменные с самого начала. \eявляется одной из escape-последовательностей, распознаваемых $'…'конструкцией.

ColorOff=$'\e[0m'       # Text Reset
BWhite=$'\e[1;37m'      # Bold White
Жиль "ТАК - перестань быть злым"
источник
6

В вашей echoкоманде две проблемы .

Я расширил переменные для краткости.

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

Первая проблема: обратные слэши теряются где-то между магией седа и магией раковины. Вы должны избежать их.

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

Все еще не работает. Может еще побег?

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

Наконец, обратные слеши проходят. Я понятия не имею, зачем нам три обратных слэша, это какая-то странная магия sed.

Вторая проблема: echo -eбессмысленно. -eразрешает интерпретацию обратной косой черты, но все echo -eинтерпретируется "test TEST test". Побег обратного слеша исходит от sed, который не заботится о них и печатает их в сыром виде.

То, что вы хотите, это:

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

с жирным тестом на выходе.

Вот полный скрипт с изменениями:

#!/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
источник
Кстати, echo -e "${BWhite}AAAA${ColorOff}"показывает `\ AAAA`. Очень жаль, потому что мне нужно хранить регулярные_цветные_константы и SED_color_constants. На самом деле, я хочу, чтобы у меня были только normal_color_constants, и исправлял параметры echo и sed, чтобы получить то, что я хочу.
ДМИТРИЙ МАЛИКОВ
Это решение довольно хрупкое (что, если $stringсодержит обратную косую черту?) И немного сложнее, чем необходимо. Чтобы понять цитирование, принимайте вещи по одному. Например, три обратные косые черты вовсе не являются магией седа: сначала идут двойные кавычки, и "\\\e"это строка из двух символов \e; тогда sed понимается \eкак « eбуквально персонаж ».
Жиль "ТАК - прекрати быть злым"