【问题标题】:Using colors with printf在 printf 中使用颜色
【发布时间】:2011-03-23 23:02:50
【问题描述】:

这样写的时候,会输出蓝色的文字:

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 的示例,该示例已定义格式。

【问题讨论】:

标签: linux bash colors printf


【解决方案1】:

我可以建议以下替代方案,而不是使用过时的终端代码。它不仅提供了更具可读性的代码,而且还允许您将颜色信息与格式说明符分开,就像您最初想要的那样。

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

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

查看我的回答HERE 了解更多颜色

【讨论】:

  • // ,这也使我不必记录代码的含义。我认为这将是帮助我们小组将脚本视为文档的一步。
  • 不仅如此,它还可以移植到比硬编码特定转义码更多的终端类型。
【解决方案2】:

您将这些部分混合在一起,而不是干净地分开它们。

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

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

【讨论】:

  • 这里有一些额外的细节:命令printf由一个格式字符串和一个根据格式打印的参数列表组成。您应该将颜色视为格式字符串的一部分,因此它们应该属于格式字符串。
  • 很好的答案,完全改变了我看待问题的方式
【解决方案3】:

这对我有用:

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

【讨论】:

  • printf "\e[1;34mThis is a blue text.\e[0m" 对我来说完全一样。
  • @PintoDoido 和 OP。但你真的读过这个问题吗?
【解决方案4】:

这是一个在终端上获取不同颜色的小程序。

#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;
}

【讨论】:

  • 这是 c 而不是 bash。
  • 已经做得更好的tput 命令有什么问题?
【解决方案5】:

这是一个使用 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";

【讨论】:

  • 您对发布到 StackOverflow 的代码的重用政策是什么?
  • @DaisukeAramaki 感谢您的提问。您可以以任何方式在任何您想要的地方使用。它在麻省理工学院许可下。如果您想合作,请随时向 Gist 提交改进:gist.github.com/arianacosta/d6d1c521d231cc09ec5fe850ae2f5be1
【解决方案6】:

我使用这个 c 代码打印彩色外壳输出。代码基于this帖子。

//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;
}

【讨论】:

  • 为什么不使用为实际终端选择合适代码的现有tput 程序?这不考虑终端类型。
  • @Toby Speight 我同意,使用 tput 是最好的解决方案。这更多的是关于基本原理。我在嵌入式平台上使用了它。
【解决方案7】:

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

dashprintf 的最新实现[1] 不会对带有 ANSI 转义字符 \e%s 格式说明符的输出着色 -- 但是, 格式说明符 %b 结合八进制 \033(相当于 ASCII ESC)将完成工作。请评论任何异常值,但 AFAIK,所有 shell 都已实现 printf 以至少使用 ASCII 八进制子集。

对于问题“使用 printf 使用颜色”的标题,设置格式的最便携方法是将%b 格式说明符组合为printf(如前面的@来自@Vlad 的987654321@),带有八进制转义\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

...第二行中的“blue”是蓝色的。

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


[1] Ref: man dash Section "Builtins" :: "printf" :: "Format"

【讨论】:

  • 不,最便携的方法是使用tput 生成它们,而不是假设一组特定于终端的转义符在任何地方都可以使用(提示:它不会)。
  • @TobySpeight,嗨!我从您的 cmets 看到其他答案,您是 tput 传道者。对于您对此答案的问题,ASCII 转义字符绝对不是“特定于终端的转义”,并且此答案不依赖于可能可用也可能不可用的额外实用程序。
  • 不,这些不仅仅是 ASCII。它们完全依赖于终端。在任何不支持您使用的特定代码的终端上使用这些,您最多只会在输出中混入垃圾(最坏的情况是意外行为)。这是我觉得恼人的事情。忽略$TERM 对您的用户来说是无礼的。
【解决方案8】:
#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 中的 printf,而不是 C.
猜你喜欢
  • 2019-12-24
  • 2016-07-04
  • 2021-08-10
  • 2021-05-11
  • 2021-10-26
  • 2016-06-15
  • 1970-01-01
  • 1970-01-01
  • 2016-11-08
相关资源
最近更新 更多