Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OSX sed: how to use the escape character in the second field of a `s` operation?

On OSX:

bash-3.2$ echo "abc" | sed 's/b/\x1b[31mz\x1b[m/'
ax1b[31mzx1b[mc

Whereas on Linux:

$ echo "abc" | sed 's/b/\x1b[31mz\x1b[m/'
azc

and the z correctly shows up red.

Is this a limitation of bash 3.2? My Linux test here runs bash 4.1.2.

The weird thing is on my linux environment at work the bash is version below 3.2, and it works there too.

Also, this might be related but is probably not:

bash-3.2$ echo "abc" | sed 's/b/^[[31mz^[[m/'
31mz$'m/'azc

Again, specific to BSD sed. It's pretty puzzling: Seems like something is causing the shell or sed to echo some mangled portion of the command to the terminal somehow? It is always preceding the correct output of the command, however. Where's that dollar sign coming from?

(don't be confused by colors in my commands (which come after the cyan unicode character that looks like a less bent > which is my prompt), I use syntax highlighting with zsh)

enter image description here

like image 905
Steven Lu Avatar asked Jun 09 '13 23:06

Steven Lu


2 Answers

OS X's version of sed doesn't do the escape substitutions you're asking for. You can get around this by using $'...' to have bash do the substitution before handing the string to sed:

$ echo "abc" | sed 's/b/\x1b[31mz\x1b[m/'
ax1b[31mzx1b[mc
$ echo "abc" | sed $'s/b/\x1b[31mz\x1b[m/'
azc

(You'll have to trust me the "z" is red in the second one.) But note that this may require that in some cases you may have to double-escape things you want sed to do the escape substitution on.

like image 178
Gordon Davisson Avatar answered Oct 22 '22 11:10

Gordon Davisson


Oh. right so the shell version does not affect this. No idea why I thought that.

The culprit is just that BSD sed doesn't do translation, so the solution is just the Ctrl+V approach of using the raw escape byte in the sed command string.

like image 42
Steven Lu Avatar answered Oct 22 '22 11:10

Steven Lu