Menggunakan warna dengan printf

90

Saat ditulis seperti ini, teks akan ditampilkan dengan warna biru:

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

Tapi saya ingin memiliki format yang ditentukan di printf:

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

Sekarang saya telah mencoba beberapa opsi cara menambahkan warna, tetapi tidak berhasil:

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

Saya bahkan mencoba menambahkan kode atribut ke format tanpa hasil. Ini tidak berfungsi dan saya tidak dapat menemukan contoh di mana pun, di mana warna ditambahkan ke printf, yang memiliki format yang ditentukan seperti dalam kasus saya.

Jernej Jerin
sumber

Jawaban:

79

Anda mencampur bagian-bagiannya dan bukannya memisahkannya dengan rapi.

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

Pada dasarnya, letakkan barang tetap dalam format dan barang variabel dalam parameter.

geekosaurus
sumber
Terima kasih atas jawaban Anda. Entah, format panjang string itu harus diletakkan di antara atribut warna.
Jernej Jerin
Cara pemformatan ini (yang baru bagi saya btw); apakah semua standar ini?
Chani
@Chani printfperintah dimodelkan setelah printf()fungsi dalam bahasa C. Di sana, parameter / argumen pertama selalu berupa formatstring yang mencakup semua pemformatan (dan mungkin juga warna) dan parameter lainnya adalah data. Jika Anda ingin mengeluarkan beberapa teks dengan gaya tertentu, masuk akal untuk meletakkan semua pemformatan dan pelarian warna dalam string format. Perhatikan bahwa format string dianggap tepercaya dan tidak boleh berisi input pengguna.
Mikko Rantalainen
Beberapa detail tambahan di sini: Perintah printfterdiri dari string format dan daftar argumen yang dicetak sesuai dengan format. Anda harus melihat warna sebagai bagian dari format-string dan oleh karena itu, mereka harus termasuk dalam format string.
kvantour
177

Daripada menggunakan kode terminal kuno, izinkan saya menyarankan alternatif berikut. Tidak hanya menyediakan kode yang lebih mudah dibaca, tetapi juga memungkinkan Anda untuk menjaga informasi warna terpisah dari penentu format seperti yang Anda inginkan.

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

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

Lihat jawaban saya DI SINI untuk warna tambahan

SiegeX
sumber
1
//, Ini juga membuatnya jadi saya tidak perlu mendokumentasikan apa arti kode itu. Saya pikir ini akan menjadi langkah maju untuk membantu grup kita melihat skrip sebagai dokumen.
Nathan Basanese
38

Ini bekerja untuk saya:

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

Dari printf(1):

%b     ARGUMENT as a string with '\' escapes interpreted, except that octal
       escapes are of the form \0 or \0NNN
Vlad
sumber
printf "\ e [1; 34mIni adalah teks biru. \ e [0m" melakukan hal yang sama untuk saya.
PintoDoido
22

Ini adalah program kecil untuk mendapatkan warna berbeda pada terminal.

#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
sumber
9
ini c dan bukan bash.
eav
14

Ini adalah fungsi kecil yang mencetak teks berwarna menggunakan skrip bash. Anda dapat menambahkan gaya sebanyak yang Anda inginkan, dan bahkan mencetak tab dan baris baru:

#!/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
sumber
2
apa kebijakan Anda tentang penggunaan kembali kode yang diposting ke StackOverflow?
Daisuke Aramaki
2
@DaisukeAramaki Terima kasih sudah bertanya. Anda dapat menggunakannya dengan cara apa pun dan di mana pun Anda inginkan. Ini di bawah lisensi MIT. Jika Anda ingin berkolaborasi, silakan kirimkan perbaikan ke Intisari: gist.github.com/arianacosta/d6d1c521d231cc09ec5fe850ae2f5be1
Arian Acosta
5

Saya menggunakan kode c ini untuk mencetak keluaran shell berwarna. Kode didasarkan pada posting ini .

//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
sumber
2

man printf.1memiliki catatan di bagian bawah: "... shell Anda mungkin memiliki versi printf...". Pertanyaan ini diberi tag bash, tetapi jika memungkinkan, saya mencoba menulis skrip portabel ke shell apa pun . dashbiasanya dasar yang baik minimum untuk portabilitas - sehingga jawabannya di sini bekerja di bash, dash, & zsh. Jika sebuah skrip berfungsi pada ketiga hal tersebut, kemungkinan besar itu portabel ke mana saja.

Implementasi terbaru dari printfin dash[1] tidak mewarnai keluaran yang diberikan penentu %sformat dengan karakter escape ANSI \e- tetapi, penentu format yang %bdikombinasikan dengan oktal \033(setara dengan ASCII ESC) akan menyelesaikan pekerjaan. Harap beri komentar untuk setiap pencilan, tetapi AFAIK, semua shell telah diimplementasikan printfuntuk menggunakan subset oktal ASCII minimal.

Untuk judul pertanyaan "Menggunakan warna dengan printf", cara paling portabel untuk menyetel pemformatan adalah dengan menggabungkan penentu %bformat untuk printf(seperti yang direferensikan dalam jawaban sebelumnya dari @Vlad) dengan escape oktal \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"

Keluaran:

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

... dan 'biru' adalah biru di baris kedua.

Penentu %-6sformat dari OP berada di tengah string format antara urutan karakter kontrol pembuka & penutup.


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

AaronDanielson
sumber
-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
sumber
2
Pertanyaannya adalah tentang printf di Bash, bukan C.
All Workers Are Essential