Sử dụng màu với printf


90

Khi được viết như thế này, nó xuất ra văn bản màu xanh lam:

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

Nhưng tôi muốn định dạng được xác định trong printf:

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

Bây giờ tôi đã thử một số tùy chọn cách thêm màu, nhưng không thành công:

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

Tôi thậm chí đã cố gắng thêm mã thuộc tính vào định dạng nhưng không thành công. Điều này không hoạt động và tôi không thể tìm thấy bất kỳ ví dụ nào, nơi màu sắc được thêm vào printf, có định dạng được xác định như trong trường hợp của tôi.

Câu trả lời:


79

Bạn đang trộn các phần với nhau thay vì tách chúng ra một cách sạch sẽ.

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

Về cơ bản, hãy đặt những thứ cố định vào định dạng và những thứ có thể thay đổi trong các tham số.


Cảm ơn vì câu trả lời của bạn. Không biết, định dạng chiều dài chuỗi đó phải được đặt giữa thuộc tính màu.
Jernej Jerin

Cách định dạng này (mới đối với tôi btw); là tất cả tiêu chuẩn này?
Chani

@Chani printflệnh được mô hình hóa sau printf()hàm trong ngôn ngữ C. Ở đó, tham số / đối số đầu tiên luôn là formatchuỗi bao gồm tất cả các định dạng (và có thể cả màu nữa) và phần còn lại của các tham số là dữ liệu. Nếu bạn muốn tạo một số văn bản với một số phong cách cụ thể, bạn nên đặt tất cả các định dạng và màu sắc thoát ra trong chuỗi định dạng. Lưu ý rằng chuỗi định dạng được coi là đáng tin cậy và không bao giờ được chứa đầu vào của người dùng.
Mikko Rantalainen

Một số chi tiết bổ sung ở đây: Lệnh printfbao gồm một chuỗi định dạng và một danh sách đối số được in theo định dạng. Bạn sẽ thấy màu sắc là một phần của chuỗi định dạng và do đó, chúng phải thuộc về chuỗi định dạng.
kvantour

177

Thay vì sử dụng mã đầu cuối cổ, tôi có thể đề xuất phương án thay thế sau đây. Nó không chỉ cung cấp mã dễ đọc hơn mà còn cho phép bạn giữ thông tin màu tách biệt với các chỉ định định dạng giống như dự định ban đầu của bạn.

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

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

Xem câu trả lời của tôi TẠI ĐÂY để biết thêm màu


1
//, Điều này cũng giúp tôi không phải ghi lại ý nghĩa của các mã. Tôi nghĩ đó sẽ là một bước tiến trong việc giúp nhóm của chúng tôi coi tập lệnh là tài liệu.
Nathan Basanese

38

Điều này phù hợp với tôi:

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

Từ 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 Đây là văn bản màu xanh lam. \ e [0m" đối với tôi cũng giống như vậy.
PintoDoido,

22

Đây là một chương trình nhỏ để có được màu khác nhau trên thiết bị đầu cuối.

#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
đây là c và không bash.
eav

14

Đây là một chức năng nhỏ để in văn bản màu bằng cách sử dụng kịch bản bash. Bạn có thể thêm bao nhiêu kiểu tùy ý, thậm chí in các tab và dòng mới:

#!/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
chính sách của bạn về việc sử dụng lại mã đã đăng lên StackOverflow là gì?
Daisuke Aramaki

2
@DaisukeAramaki Cảm ơn bạn đã hỏi. Bạn có thể sử dụng theo bất kỳ cách nào và bất cứ nơi nào bạn muốn. Nó theo giấy phép MIT. Nếu bạn muốn cộng tác, cảm thấy tự do để trình cải tiến cho Gist: gist.github.com/arianacosta/d6d1c521d231cc09ec5fe850ae2f5be1
Arian Acosta

5

Tôi sử dụng mã c này để in đầu ra vỏ màu. Mã dựa trên bài đăng này .

//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.1có ghi chú ở dưới cùng: "... shell của bạn có thể có phiên bản riêng của printf...". Câu hỏi này được gắn thẻ cho bash, nhưng nếu có thể, tôi cố gắng viết script di động vào bất kỳ trình bao nào . dashthường là một cơ sở tốt tối thiểu cho tính di động - vì vậy câu trả lời ở đây làm việc tại bash, dash, & zsh. Nếu một tập lệnh hoạt động trong 3 điều đó, rất có thể nó có thể di động đến bất cứ đâu.

Việc triển khai mới nhất của printftrong dash[1] không tô màu đầu ra với%s định dạng có ký tự thoát ANSI \e- nhưng, một mã định dạng %bkết hợp với bát phân \033(tương đương với ASCII ESC) sẽ hoàn thành công việc. Vui lòng nhận xét nếu có bất kỳ ngoại lệ nào, nhưng AFAIK, tất cả các shell đã triển khai printfđể sử dụng tập hợp con bát phân ASCII ở mức tối thiểu.

Đến tiêu đề của câu hỏi "Sử dụng màu sắc với printf", tính di động nhất cách để thiết lập định dạng là kết hợp các %bspecifier định dạng cho printf(như tham chiếu trong một sớm câu trả lời từ @Vlad) với một lối thoát bát phân \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"

Kết quả đầu ra:

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

... và 'blue' là màu xanh lam ở dòng thứ hai.

Bộ %-6schỉ định định dạng từ OP nằm ở giữa chuỗi định dạng giữa chuỗi ký tự điều khiển mở và đóng.


[1] Tham khảo: man dashPhần "Nội trang" :: "printf" :: "Định dạng"


-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
Câu hỏi đặt ra là về printf trong Bash, không C.
Tất cả các công nhân đang Essential
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.