Использование цветов с 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, который имеет определенный формат, как в моем случае.

Ерней Джерин
источник

Ответы:

79

Вы смешиваете части вместе, вместо того, чтобы аккуратно их разделять.

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

По сути, поместите фиксированный материал в формат, а переменный в параметры.

гикозавр
источник
Спасибо за ваш ответ. Не знал, что формат длины строки должен быть помещен между атрибутом цвета.
Jernej Jerin
Этот способ форматирования (который, кстати, для меня новый); это все стандартно?
Chani
@Chani printfкоманда смоделирована после printf()функции на языке C. Здесь первым параметром / аргументом всегда является formatстрока, которая включает все форматирование (и, возможно, цвета тоже), а остальные параметры - это данные. Если вы хотите поместить текст в каком-то определенном стиле, имеет смысл поместить все форматирование и экранирование цвета в строку формата. Обратите внимание, что строка формата считается надежной и никогда не должна содержать пользовательский ввод.
Микко Ранталайнен
Некоторые дополнительные сведения: команда printfсостоит из строки формата и списка аргументов, которые печатаются в соответствии с форматом. Вы должны видеть цвета как часть строки формата и, следовательно, они должны принадлежать строке формата.
квантур
177

Вместо того, чтобы использовать устаревшие терминальные коды, могу предложить следующую альтернативу. Он не только обеспечивает более читаемый код, но также позволяет хранить информацию о цвете отдельно от спецификаторов формата, как вы изначально планировали.

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

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

Смотрите мой ответ ЗДЕСЬ для дополнительных цветов

SiegeX
источник
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 05
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
2
@DaisukeAramaki Спасибо за вопрос. Вы можете использовать как хотите и где угодно. Это под лицензией MIT. Если вы хотите сотрудничать, не стесняйтесь вносить улучшения в Gist: gist.github.com/arianacosta/d6d1c521d231cc09ec5fe850ae2f5be1
Arian Acosta
5

Я использую этот код для вывода цветной оболочки. Код основан на этом посте.

//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, но, если возможно, я стараюсь писать сценарии, переносимые на любую оболочку. dashкак правило, хорошие минимальный базовый уровень для портативности - так что ответ здесь работает bash, dash, и zsh. Если сценарий работает в этих 3, он, скорее всего, переносится куда угодно.

Последняя реализация printfв dash[1] не раскрасить выход дан %sспецификатор формата с экранирующего символа ANSI \e- но, формат спецификатора в %bсочетании с восьмеричной \033(эквивалент ASCII ESC) будет получить работу. Прокомментируйте любые выбросы, но AFAIK, все оболочки реализованыprintf использование восьмеричного подмножества ASCII как минимум.

К заголовку вопроса «Использование цветов с printf» наиболее переносимый способ установить форматирование - это объединить %bспецификатор формата для printf(как указано в предыдущем ответе @Vlad) с восьмеричным escape-символом \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Раздел "Встроенные" :: "printf" :: "Формат"

Аарон Дэниелсон
источник
-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;
}
Thlv
источник
2
Речь идет о printf в Bash, а не о C.
All Workers are Essential