34

How can I output colored text using "printf" on both Mac OS X and Linux?

Brendan Long
  • 53,280
  • 21
  • 146
  • 188
Mike
  • 23,892
  • 18
  • 70
  • 90

3 Answers3

35

You can use the ANSI colour codes. Here's an example program:

#include <stdio.h>
    
int main(int argc, char *argv[])
{
  printf("%c[1;31mHello, world!\n", 27); // red
  printf("%c[1;32mHello, world!\n", 27); // green
  printf("%c[1;33mHello, world!\n", 27); // yellow
  printf("%c[1;34mHello, world!\n", 27); // blue
  return 0;
}

The 27 is the escape character. You can use \e if you prefer.

There are lists of all the codes all over the web. Here is one.

KlemenPl
  • 354
  • 4
  • 21
Carl Norum
  • 219,201
  • 40
  • 422
  • 469
  • 1
    Assuming ANSI escape sequences, as popularized by VT100 derivatives (VT1xx didn't have color). And you could have used `"\033"` instead of `"%c", 27`. – ephemient Mar 01 '10 at 01:56
  • @ephemient, even `\e` worked on my machine. OS X's terminal and most linux console apps support the ANSI escape sequences, so I think it satisfies his question. – Carl Norum Mar 01 '10 at 01:59
  • If I remember fine, `\e` is gcc-only. – Jack Oct 10 '12 at 20:16
  • 1
    Any chance you can explain in more detail what is going on here for a newbie? There seems to be nothing in the printf documentation about it. What causes this syntax to work in this way? Just curious to understand it better! Thank you :) – Hendeca Jun 15 '14 at 01:09
  • @Hendeca, that's because it has nothing to do with `printf`. It's that the terminal program itself interprets these escape codes as commands to change the colour it uses on screen. – Carl Norum Jun 15 '14 at 04:07
6

Another option is:

# Define some colors first (you can put this in your .bashrc file):
red='\e[0;31m'
RED='\e[1;31m'
blue='\e[0;34m'
BLUE='\e[1;34m'
cyan='\e[0;36m'
CYAN='\e[1;36m'
green='\e[0;32m'
GREEN='\e[1;32m'
yellow='\e[0;33m'
YELLOW='\e[1;33m'
NC='\e[0m'
#################

Then you can type in the terminal:

echo -e "${RED}This is an error${NC}"
echo -e "${YELLOW}This is a warning${NC}"
echo -e "${GREEN}Everythings fine!${NC}"

Do not forget the ${NC} at the end. NC stands for "no color", which means that after your sentence, it will revert back to normal color. If you forget it, the whole prompt and commands afterwards will be in the color you specified (of course you can type 'echo -e "${NS}"' to change it back).

lugte098
  • 2,271
  • 5
  • 21
  • 30
  • This doesn't seem to work in terminal on mac (OS X v10.9.1) - I didn't put it in the .bashrc, just defined it within the shell on the command line - but the text was printed directly. – Anand Feb 24 '14 at 14:01
  • 1
    The question was about the 'printf' command, not terminal commands. Moreover, a cross platform solution was requested, 'put this in your .bashrc' isn't that. – TimZaman Aug 15 '14 at 08:46
  • @TimZaman Well, technically the OP requested a solution "on both Mac OS X and Linux", so putting it in .bashrc is exactly that. Though i do agree that it isn't answering how to do it using "printf". I do feel the need to point out that i gave my answer as an alternative: "Another option is:", rather than stating this actually was the answer. – lugte098 Dec 10 '14 at 16:04
2

For the best portability, query the terminfo database. In shell,

colors=(black red green yellow blue magenta cyan white)
for ((i = 0; i < ${#colors[*]}; i++)); do
    ((j=(i+1)%${#colors[*]}))
    printf '%s%s%s on %s%s\n' "$(tput setaf $i)" "$(tput setab $j)" \
            "${colors[i]}" "${colors[j]}" "$(tput op)"
done

will print out

black on red
red on green
green on yellow
yellow on blue
blue on magenta
magenta on cyan
cyan on white
white on black

but in color.

ephemient
  • 198,619
  • 38
  • 280
  • 391
  • +1 nice, but how do I do this from C? I can't seem to find library equivalents for tput - maybe yank it directly from open source? – kfmfe04 Feb 02 '12 at 18:51