man printf.1tem uma nota na parte inferior: "... seu shell pode ter sua própria versão de printf...". Esta questão está marcada para bash, mas se possível, tento escrever scripts portáteis para qualquer shell. dashé geralmente uma base boa mínimo para portabilidade - então a resposta aqui trabalha em bash, dash, e zsh. Se um script funcionar nesses 3, é mais provável que seja portátil para qualquer lugar.
A implementação mais recente do printfin dash[1] não coloriza a saída dado um %sespecificador de formato com um caractere de escape ANSI \e- mas, um especificador de formato %bcombinado com octal \033(equivalente a um ASCII ESC) fará o trabalho. Por favor, comente para quaisquer outliers, mas AFAIK, todos os shells foram implementados printfpara usar o subconjunto octal ASCII no mínimo.
Para o título da pergunta "Usando cores com printf", a maneira mais portátil de definir a formatação é combinar o %bespecificador de formato para printf(como referenciado em uma resposta anterior de @Vlad) com um escape octal \033.
portable-color.sh
P="\033["
BLUE=34
printf "-> This is %s %-6s %s text \n" $P"1;"$BLUE"m" "blue" $P"0m"
printf "-> This is %b %-6s %b text \n" $P"1;"$BLUE"m" "blue" $P"0m"
Saídas:
$ ./portable-color.sh
-> This is \033[1;34m blue \033[0m text
-> This is blue text
... e 'azul' é azul na segunda linha.
O %-6sespecificador de formato do OP está no meio da string de formato entre as sequências de caracteres de controle de abertura e fechamento.
[1] Ref: man dashSeção "Embutidos" :: "printf" :: "Formato"
printfconsiste em uma string de formato e uma lista de argumentos impressa de acordo com o formato. Você deve ver as cores como parte da string de formato e, portanto, elas devem pertencer à string de formato.