在 printf 中使用颜色

像这样编写时,它输出蓝色的文本:

printf "\e[1;34mThis is a blue text.\e[0m"

但我想在 printf 中定义格式:

printf '%-6s' "This is text"

现在我尝试了几种添加颜色的方法,但都没有成功:

printf '%-6s' "\e[1;34mThis is text\e[0m"

我甚至尝试添加属性代码来格式化,但没有成功。 这不起作用,我找不到任何地方的例子,其中的颜色添加到 printf,这已定义的格式,在我的情况下。

179300 次浏览

你把这些部分混合在一起,而不是把它们分开。

printf '\e[1;34m%-6s\e[m' "This is text"

基本上,把固定的东西放在格式里,把可变的东西放在参数里。

这对我有用:

printf "%b" "\e[1;34mThis is a blue text.\e[0m"

来自 printf(1):

%b     ARGUMENT as a string with '\' escapes interpreted, except that octal
escapes are of the form \0 or \0NNN

与其使用古老的终端代码,我可以提出以下备选方案吗。它不仅提供了更具可读性的代码,而且还允许将颜色信息与格式说明符分开,就像您最初希望的那样。

blue=$(tput setaf 4)
normal=$(tput sgr0)


printf "%40s\n" "${blue}This text is blue${normal}"

有关其他颜色,请参阅我的答案 给你

这是一个小程序,得到不同的终端颜色。

#include <stdio.h>


#define KNRM  "\x1B[0m"
#define KRED  "\x1B[31m"
#define KGRN  "\x1B[32m"
#define KYEL  "\x1B[33m"
#define KBLU  "\x1B[34m"
#define KMAG  "\x1B[35m"
#define KCYN  "\x1B[36m"
#define KWHT  "\x1B[37m"


int main()
{
printf("%sred\n", KRED);
printf("%sgreen\n", KGRN);
printf("%syellow\n", KYEL);
printf("%sblue\n", KBLU);
printf("%smagenta\n", KMAG);
printf("%scyan\n", KCYN);
printf("%swhite\n", KWHT);
printf("%snormal\n", KNRM);


return 0;
}
#include <stdio.h>


//fonts color
#define FBLACK      "\033[30;"
#define FRED        "\033[31;"
#define FGREEN      "\033[32;"
#define FYELLOW     "\033[33;"
#define FBLUE       "\033[34;"
#define FPURPLE     "\033[35;"
#define D_FGREEN    "\033[6;"
#define FWHITE      "\033[7;"
#define FCYAN       "\x1b[36m"


//background color
#define BBLACK      "40m"
#define BRED        "41m"
#define BGREEN      "42m"
#define BYELLOW     "43m"
#define BBLUE       "44m"
#define BPURPLE     "45m"
#define D_BGREEN    "46m"
#define BWHITE      "47m"


//end color
#define NONE        "\033[0m"


int main(int argc, char *argv[])
{
printf(D_FGREEN BBLUE"Change color!\n"NONE);


return 0;
}

这是一个使用 bash 脚本打印彩色文本的小函数。您可以添加任意多的样式,甚至可以打印制表符和新行:

#!/bin/bash


# prints colored text
print_style () {


if [ "$2" == "info" ] ; then
COLOR="96m";
elif [ "$2" == "success" ] ; then
COLOR="92m";
elif [ "$2" == "warning" ] ; then
COLOR="93m";
elif [ "$2" == "danger" ] ; then
COLOR="91m";
else #default color
COLOR="0m";
fi


STARTCOLOR="\e[$COLOR";
ENDCOLOR="\e[0m";


printf "$STARTCOLOR%b$ENDCOLOR" "$1";
}


print_style "This is a green text " "success";
print_style "This is a yellow text " "warning";
print_style "This is a light blue with a \t tab " "info";
print_style "This is a red text with a \n new line " "danger";
print_style "This has no color";

我用这个代码打印彩色外壳输出。该代码是基于 这个后。

//General Formatting
#define GEN_FORMAT_RESET                "0"
#define GEN_FORMAT_BRIGHT               "1"
#define GEN_FORMAT_DIM                  "2"
#define GEN_FORMAT_UNDERSCORE           "3"
#define GEN_FORMAT_BLINK                "4"
#define GEN_FORMAT_REVERSE              "5"
#define GEN_FORMAT_HIDDEN               "6"


//Foreground Colors
#define FOREGROUND_COL_BLACK            "30"
#define FOREGROUND_COL_RED              "31"
#define FOREGROUND_COL_GREEN            "32"
#define FOREGROUND_COL_YELLOW           "33"
#define FOREGROUND_COL_BLUE             "34"
#define FOREGROUND_COL_MAGENTA          "35"
#define FOREGROUND_COL_CYAN             "36"
#define FOREGROUND_COL_WHITE            "37"


//Background Colors
#define BACKGROUND_COL_BLACK            "40"
#define BACKGROUND_COL_RED              "41"
#define BACKGROUND_COL_GREEN            "42"
#define BACKGROUND_COL_YELLOW           "43"
#define BACKGROUND_COL_BLUE             "44"
#define BACKGROUND_COL_MAGENTA          "45"
#define BACKGROUND_COL_CYAN             "46"
#define BACKGROUND_COL_WHITE            "47"


#define SHELL_COLOR_ESCAPE_SEQ(X) "\x1b["X"m"
#define SHELL_FORMAT_RESET  ANSI_COLOR_ESCAPE_SEQ(GEN_FORMAT_RESET)


int main(int argc, char* argv[])
{
//The long way
fputs(SHELL_COLOR_ESCAPE_SEQ(GEN_FORMAT_DIM";"FOREGROUND_COL_YELLOW), stdout);
fputs("Text in gold\n", stdout);
fputs(SHELL_FORMAT_RESET, stdout);
fputs("Text in default color\n", stdout);


//The short way
fputs(SHELL_COLOR_ESCAPE_SEQ(GEN_FORMAT_DIM";"FOREGROUND_COL_YELLOW)"Text in gold\n"SHELL_FORMAT_RESET"Text in default color\n", stdout);


return 0;
}

man printf.1在底部有一个注释: “ ... ... 您的 shell 可能有自己的 printf版本... ...”。这个问题被标记为 bash,但是如果可能的话,我尝试编写可移植到 任何 shell 的脚本。dash通常是一个良好的可移植性的最低基线-所以这里的答案在 bashdashzsh中起作用。如果一个脚本可以在这3种情况下工作,那么它很可能可以移植到任何地方。

dash[1]printf的最新实现没有对输出进行彩色化,因为 %s格式说明符带有 ANSI 转义字符 \e—— 但是,格式说明符 %b与八进制 \033(相当于 ASCII ESC)的组合可以完成这项工作。请注释任何异常值,但 AFAIK,所有外壳程序已实现 printf使用 ASCII 八进制子集在最低限度。

对于题目“使用颜色和 printf”,最常用的 便携式的设置格式的方法是将 printf%b格式说明符(如之前@Vlad 的 回答中所引用的)与八进制转义 \033结合起来。


Portable-color.sh

#/bin/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"

产出:

$ ./portable-color.sh
-> This is \033[1;34m blue   \033[0m text
-> This is  blue    text

“蓝色”在第二行是蓝色的。

来自 OP 的 %-6s格式说明符位于开始和结束控制字符序列之间的格式字符串的中间。


[1]参考文献: man dash节“内容”: : “ printf”: : “格式”

color() {
STARTCOLOR="\e[$2";
ENDCOLOR="\e[0m";
export "$1"="$STARTCOLOR%b$ENDCOLOR"
}
color info 96m
color success 92m
color warning 93m
color danger 91m


printf $success'\n' "This will be green";

这个可以显示你所有的颜色。如果颜色可能不可用,您可能需要一种备用方法。你可以写:

printf ${danger:-'%b'}'\n' "This will be red and would not break if color is unavailable";

或者,如果您想要通过多行编写消息,只需省略 n’

printf $info "This is ";
printf $info "blue!";
printf '\n'