Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Is it sed or echo problem? What I'm doing wrong?

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

Actually, I suppose to get TEST with bold highlighting.

share|improve this question
add comment

2 Answers

up vote 3 down vote accepted

sed doesn't treat \e as an escape sequence. With GNU sed, and most other sed implementations out there, \e in an s replacement text just means e. The only backslash escapes you can use portably in s replacement text are \\ to mean a backslash, \& to mean a literal &, \/ (where / is the delimiter character) for a literal /, and \1 through \9 for backreferences. GNU sed and BusyBox (but not e.g. OpenBSD sed) adds \n for a newline. Thus the output of your sed command has a literal e.

In bash, you can easily put a literal escape character in your variables from the start. \e is one of the escape sequences recognized by the $'…' construct.

ColorOff=$'\e[0m'       # Text Reset
BWhite=$'\e[1;37m'      # Bold White
share|improve this answer
add comment

There are two problems in your echo command.

I expanded the variables for brevity.

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

First problem: the backslashes are lost somewhere between sed magic and shell magic. You have to escape them.

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

Still doesn't work. Maybe more escaping?

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

Finaly the backslashes are coming through. I have no idea why we need three backslashes, that is some weird sed magic.

Second problem: the echo -e is pointless. -e enables interpretation of backslash escapes, but all echo -e gets to interpret is "test TEST test". The backslash escapes are coming from sed, which does not care about them and prints them raw.

What you want is this:

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

with bold TEST in output.

Here is the full script with the changes:

#!/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")
share|improve this answer
    
Btw, echo -e "${BWhite}AAAA${ColorOff}" shows `\AAAA`. It's a pity, because than I need to keep regular_color_constants and SED_color_constants. Actually, I want to have only regular_color_constants, and fix echo and sed options to get what I want. –  ДМИТРИЙ МАЛИКОВ Aug 23 '11 at 14:02
    
That solution is rather fragile (what if $string contains a backslash?) and is quite a bit more complicated than necessary. To understand quoting, take things one at a time. E.g. the three backslashes aren't sed magic at all: first there are double quotes, and "\\\e" is the two-character string \e; then sed understands \e as “the character e literally”. –  Gilles Aug 23 '11 at 22:25
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.