46

I have a ksh script that must work on both linux and solaris. I'm trying to color the output of specific commands. It works on linux (specifically RHEL6), but not on solaris (SunOS 5.10).

Command on linux (the output "test" is correctly colored red):

[amartin@linuxbox:~]$ echo "test" | sed 's,.*,\x1B[31m&\x1B[0m,'
test

Command on solaris (the output "test" is not colored):

[amartin@sunbox:~]$ echo "test" | sed 's,.*,\x1B[31m&\x1B[0m,'
x1B[31mtestx1B[0m

Is there a way to craft this command such that the output is red, without the raw codes in the output? I can't change the 'echo' command because that's just a fill in for the command I'm actually running.

4 Answers 4

50

\xNN is an escape sequence in GNU sed, but it is not standard, and in particular it is not available on Solaris.

You can include a literal escape character in your script, but that would make it hard to read and edit.

You can use printf to generate an escape character. It understands octal escapes, not hexadecimal.

esc=$(printf '\033')
echo "test" | sed "s,.*,${esc}[31m&${esc}[0m,"

You can call tput to generate the replacement text in the call to sed. This command looks up escape sequences in the terminfo database. In theory, using tput makes your script more portable, but in practice you're unlikely to encounter a terminal that doesn't use ANSI escape codes.

echo "test" | sed "s,.*,$(tput setaf 1)&$(tput sgr0),"
1
  • this works great to colorize on a cat |sed too thx! Jun 14, 2014 at 2:29
9

It would be easier to use tput

tput setaf 1; somecommand; tput sgr0

or

tput setaf 1
somecommand
tput sgr0

This sets the foreground to red, runs somecommand which will then display the output in red then clears the color sequence. This works at least with bash, zsh and ksh.

See tmux(1) and terminfo(5) for more information about what you can do with tput.

3
  • 1
    thanks for the response. As I said earlier, I can't change the echo command. 'echo' is just a stand-in for the process I'm calling, which I cannot change. Is it possible to use sed with tput somehow? Also, when I run that command on sunOS 5.10 I don't see any colors.
    – acm
    Aug 20, 2012 at 19:52
  • I updated it to break it apart into separate commands.
    – bahamat
    Aug 20, 2012 at 19:55
  • This is better than my current implementation in that it does not print raw ascii codes on solaris. However (for whatever reason), it doesn't color the output of 'somecommand' on solaris. It does on linux. I have accepted @Gilles answer, which does both. Thank you.
    – acm
    Aug 21, 2012 at 16:16
6

There is an even easier way:

To know exactly what byte correspond to the escape character \033, here is what you can do:

printf "\033" | xxd -p

And you get

1b

So the escape sequence \033 correspond to the byte 0b00011011 in binary, 27 in decimal, or 1b in hexadecimal.

And good news: sed knows hexadecimal codes !

echo "color test" | sed 's,color,\x1b[31m&\x1b[0m,'

This is a much nicer solution, when you know your hex.

1

Some terminals (like bash in iterm for me) allow you to hit the keys "ctrl-v" followed by "ctrl+[" and it will put the literal escape character into the input string. If it works, you will probably see the characters "^[" printed on screen, but if you move your cursor around it, it will treat it as one character because it really is behind the scenes.

To understand what's happening (and to test if this is possible), you can type ctrl+v followed by ctrl+i. You should see that the tab character was inserted into your prompt string. There's CS history for why this is the case: but it turns out that really old keyboard had ctrl+I hard wired to send the tab character; and the tab key send that same electrical signal too.

For that legacy reason, bash for many terminals still interprets certain ctrl codes to map to those same characters.

Ctrl+I maps to tab character, and ctrl+[ happens to match to the ascii escape character.

1
  • In iTerm ctrl-v followed by esc/tab inserts the escaped character. This also works in vim.
    – Daghall
    Jun 19 at 9:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .