Verwenden von Farben mit printf

88

Wenn es so geschrieben wird, wird Text in Blau ausgegeben:

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

Aber ich möchte, dass das Format in printf definiert wird:

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

Jetzt habe ich verschiedene Optionen zum Hinzufügen von Farbe ausprobiert, ohne Erfolg:

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

Ich habe sogar erfolglos versucht, dem Format Attributcode hinzuzufügen. Dies funktioniert nicht und ich kann nirgendwo ein Beispiel finden, in dem Farben zu printf hinzugefügt werden, dessen Format wie in meinem Fall definiert ist.

Jernej Jerin
quelle

Antworten:

79

Sie mischen die Teile zusammen, anstatt sie sauber zu trennen.

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

Grundsätzlich setzen Sie das feste Zeug in das Format und das variable Zeug in die Parameter.

Geekosaurier
quelle
Danke für deine Antwort. Wusste nicht, dass das Stringlängenformat zwischen die Farbattribute gesetzt werden muss.
Jernej Jerin
Diese Art der Formatierung (die mir übrigens neu ist); ist das alles Standard?
Chani
@Chani Der printfBefehl ist der printf()Funktion in der Sprache C nachempfunden . Dort ist der erste Parameter / das erste Argument immer die formatZeichenfolge, die alle Formatierungen (und möglicherweise auch Farben) enthält, und der Rest der Parameter sind Daten. Wenn Sie Text mit einem bestimmten Stil ausgeben möchten, ist es sinnvoll, alle Formatierungs- und Farb-Escapezeichen in die Formatzeichenfolge einzufügen. Beachten Sie, dass die Formatzeichenfolge als vertrauenswürdig gilt und niemals Benutzereingaben enthalten sollte.
Mikko Rantalainen
Einige zusätzliche Details hier: Der Befehl printfbesteht aus einer Formatzeichenfolge und einer Argumentliste, die entsprechend dem Format gedruckt wird. Sie sollten Farben als Teil der Formatzeichenfolge sehen und sie sollten daher zur Formatzeichenfolge gehören.
kvantour
174

Anstatt archaische Terminalcodes zu verwenden, kann ich die folgende Alternative vorschlagen. Es bietet nicht nur besser lesbaren Code, sondern ermöglicht es Ihnen auch, die Farbinformationen von den Formatspezifizierern getrennt zu halten, wie Sie es ursprünglich beabsichtigt hatten.

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

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

Siehe meine Antwort HIER für zusätzliche Farben

SiegeX
quelle
1
//, Das macht es auch so, dass ich nicht dokumentieren muss, was die Codes bedeuten. Ich denke, es wird ein Schritt nach vorne sein, um unserer Gruppe zu helfen, Skripte als Dokumente zu sehen.
Nathan Basanese
36

Das funktioniert bei mir:

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

Von printf(1):

%b     ARGUMENT as a string with '\' escapes interpreted, except that octal
       escapes are of the form \0 or \0NNN
Vlad
quelle
printf "\ e [1; 34mDies ist ein blauer Text. \ e [0m" macht genau das gleiche für mich.
PintoDoido
22

Dies ist ein kleines Programm, um auf dem Terminal eine andere Farbe zu erhalten.

#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;
}
Kritpal Singh
quelle
8
das ist c und nicht bash.
eav
14

Dies ist eine kleine Funktion, die farbigen Text mithilfe von Bash-Skripten druckt. Sie können beliebig viele Stile hinzufügen und sogar Registerkarten und neue Zeilen drucken:

#!/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";
Arian Acosta
quelle
1
Wie lauten Ihre Richtlinien zur Wiederverwendung von Code, der in StackOverflow veröffentlicht wurde?
Daisuke Aramaki
2
@DaisukeAramaki Danke, dass du gefragt hast. Sie können auf jede Art und Weise und an jedem beliebigen Ort verwenden. Es steht unter der MIT-Lizenz. Wenn Sie zusammenarbeiten möchten, können Sie Verbesserungen an Gist einreichen: gist.github.com/arianacosta/d6d1c521d231cc09ec5fe850ae2f5be1
Arian Acosta
5

Ich verwende diesen C-Code zum Drucken der farbigen Shell-Ausgabe. Der Code basiert auf diesem Beitrag.

//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;
}
Jonny Schubert
quelle
2

man printf.1hat unten einen Hinweis: "... Ihre Shell hat möglicherweise eine eigene Version von printf...". Diese Frage ist markiert bash, aber wenn möglich, versuche ich, Skripte zu schreiben, die auf eine beliebige Shell portierbar sind . dashin der Regel ist eine gute Mindeststandards für Portabilität - so die Antwort hier arbeitet bash, dash&zsh . Wenn ein Skript in diesen 3 funktioniert, ist es höchstwahrscheinlich auf nahezu jeden Ort portierbar.

Die neueste Implementierung der printfin dash[1] nicht kolorieren Ausgang ein bestimmter %sFormatspezifizierer mit einem ANSI - Escape - Zeichen \e- aber ein Spezifizierer Format %bmit Oktal kombiniert \033(entspricht einem ASCII ESC) wird den Job erledigen. Bitte kommentieren Sie alle Ausreißer, aber AFAIK, alle Shells wurden implementiert printf, um die oktale ASCII-Teilmenge mindestens zu verwenden.

Zum Titel der Frage "Verwenden von Farben mit printf" besteht die portabelste Methode zum Festlegen der Formatierung darin, den %bFormatbezeichner für printf(wie in einer früheren Antwort von @Vlad angegeben) mit einem oktalen Escapezeichen zu kombinieren \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"

Ausgänge:

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

... und 'blau' ist in der zweiten Zeile blau.

Der %-6sFormatbezeichner aus dem OP befindet sich in der Mitte der Formatzeichenfolge zwischen den Steuerzeichenfolgen zum Öffnen und Schließen.


[1] Ref: man dashAbschnitt "Builtins" :: "printf" :: "Format"

Aaron Danielson
quelle
-1
#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
quelle
2
Die Frage ist über printf in Bash, nicht C.
Alle Arbeiter sind wesentlich