在printf中使用颜色


90

当这样写时,它以蓝色输出文本:

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

Answers:


79

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

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

基本上,将固定内容放入格式,将变量内容放入参数。


谢谢你的穿衣。不知道,字符串长度格式必须放在颜色属性之间。
Jernej Jerin 2011年

这种格式化方式(顺便说一句对我来说是新的);这是所有标准吗?
Chani 2014年

@Chani该printf命令printf()以C语言的功能为蓝本。在那里,第一个参数/参数始终是format包含所有格式(可能还包括颜色)的字符串,其余参数为数据。如果要以某种特定样式显示一些文本,则将所有格式和颜色转义符放入格式字符串中是有意义的。请注意,格式字符串被认为是受信任的,并且永远不应包含用户输入。
Mikko Rantalainen

这里有一些额外的细节:该命令printf格式字符串和根据格式打印的参数列表组成。您应该将颜色视为格式字符串的一部分,因此,它们应该属于格式字符串。
kvantour

177

我可以使用以下替代方法,而不是使用古老的终端代码。它不仅提供了更具可读性的代码,而且还使您能够按照最初的意图将颜色信息与格式说明符分开。

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

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

见我的回答这里的其他颜色


1
//,这也使它不必记录代码的含义。我认为这将是帮助我们小组将脚本视为文档的第一步。
内森·巴萨内斯

38

这对我有用:

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; 34m”这是一个蓝色文本。\ e [0m“对我来说完全一样。
PintoDoido

22

这是一个小程序,可以在终端上获得不同的颜色。

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

9
这是c而不是bash。
eav

14

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

2
您对重新使用发布到StackOverflow的代码有何政策?
荒木大辅(Daisuke Aramaki),

2
@DaisukeAramaki感谢您的询问。您可以以任何方式在任何地方使用。它已获得MIT许可。如果您想合作,请随时向Gist提交改进意见:gist.github.com/arianacosta/d6d1c521d231cc09ec5fe850ae2f5be1
Arian Acosta

5

我使用此C代码来打印彩色外壳输出。该代码基于帖子。

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

2

man printf.1在底部有一个注释:“ ...您的外壳可能具有自己的版本printf...”。这个问题被标记为bash,但是,如果有可能,我尝试编写可移植到任何shell的脚本。 dash通常是便携的好最低底线-这样的答案在这里工作的bashdash,和zsh。如果脚本可以在这3个脚本中工作,那么它很可能可以移植到几乎任何地方。

[1]中的最新实现不会printf在给定带有ANSI转义字符的格式说明符的情况下对输出进行着色-但是,将格式说明符与八进制(等效于ASCII )结合起来就可以完成工作。请评论任何异常值,但是AFAIK,所有shell均已实现dash%s\e%b\033ESCprintf了使用ASCII八进制子集的最低要求。

对于“在printf中使用颜色”问题的标题,设置格式的最可移植的方法是将%b格式说明符printf(如@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

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

%-6s从OP格式说明是在开合控制字符序列之间的格式串的中间。


[1]参考:man dash“ Builtins”部分::“ printf” ::“ Format”


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

2
现在的问题是关于printf的Bash中,没有C.
所有工人都基本
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.