Usare i colori con printf


94

Quando è scritto in questo modo, restituisce il testo in blu:

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

Ma voglio che il formato sia definito in printf:

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

Ora ho provato diverse opzioni su come aggiungere il colore, senza successo:

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

Ho anche provato ad aggiungere il codice dell'attributo al formato senza successo. Questo non funziona e non riesco a trovare da nessuna parte un esempio, in cui i colori vengono aggiunti a printf, che ha formato definito come nel mio caso.

Risposte:


81

Stai mescolando le parti insieme invece di separarle in modo pulito.

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

Fondamentalmente, metti le cose fisse nel formato e le cose variabili nei parametri.


Alcuni dettagli extra qui: Il comando printfconsiste in una stringa di formato e un elenco di argomenti che vengono stampati in base al formato. Dovresti vedere i colori come parte della stringa di formato e quindi dovrebbero appartenere alla stringa di formato.
kvantour

ottima risposta, completamente cambiato il modo in cui guardavo il problema
Steven Penny

179

Piuttosto che usare codici terminali arcaici, posso suggerire la seguente alternativa. Non solo fornisce un codice più leggibile, ma consente anche di mantenere le informazioni sul colore separate dagli identificatori di formato proprio come originariamente previsto.

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

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

Vedi la mia risposta QUI per ulteriori colori


1
//, Questo fa anche in modo che non debba documentare il significato dei codici. Penso che sarà un passo avanti per aiutare il nostro gruppo a vedere gli script come documenti.
Nathan Basanese

37

Questo funziona per me:

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

Da printf(1):

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

printf "\ e [1; 34mQuesto è un testo blu. \ e [0m" fa esattamente lo stesso per me.
PintoDoido

20

Questo è un piccolo programma per ottenere colori diversi sul terminale.

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

11
questo è ce non bash.
eav

14

Questa è una piccola funzione che stampa testo colorato usando lo scripting bash. Puoi aggiungere tutti gli stili che desideri e persino stampare schede e nuove righe:

#!/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
qual è la tua politica sul riutilizzo del codice pubblicato su StackOverflow?
Daisuke Aramaki

2
@DaisukeAramaki Grazie per avermelo chiesto. Puoi usarlo in qualsiasi modo e ovunque tu voglia. È sotto la licenza MIT. Se vuoi collaborare, sentiti libero di inviare miglioramenti al Gist: gist.github.com/arianacosta/d6d1c521d231cc09ec5fe850ae2f5be1
Arian Acosta

3

Uso questo codice c per stampare l'output della shell colorata. Il codice è basato su questo post.

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

1

man printf.1ha una nota in fondo: "... la tua shell potrebbe avere la sua versione di printf...". Questa domanda è contrassegnata bash, ma se possibile, cerco di scrivere script portabili su qualsiasi shell. dashè di solito una linea di base minima buona per la portabilità - quindi la risposta qui lavora in bash, dash, & zsh. Se uno script funziona in quei 3, è molto probabilmente portabile praticamente ovunque.

L'ultima implementazione di printfa dash[1] non uscita Colorize dato un %sidentificatore di formato con un carattere di escape ANSI \e- ma, un identificatore di formato %bcombinato con ottale \033(equivalente a un ASCII ESC) otterrà il lavoro fatto. Si prega di commentare per eventuali valori anomali, ma AFAIK, tutte le shell sono state implementate printfper utilizzare il sottoinsieme ottale ASCII come minimo.

Al titolo della domanda "Usare i colori con printf", il modo più portabile per impostare la formattazione è combinare l' identificatore di %bformato per printf(come indicato in una risposta precedente da @Vlad) con un escape ottale \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"

Uscite:

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

... e "blu" è blu nella seconda riga.

L' %-6sidentificatore di formato dall'OP si trova al centro della stringa di formato tra le sequenze di caratteri di controllo di apertura e chiusura.


[1] Rif: man dashSezione "Builtins" :: "printf" :: "Format"


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

3
La domanda riguarda printf in Bash, non C.
Tutti i lavoratori sono essenziali
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.