web-dev-qa-db-ja.com

printfで色を使用する

このように書くと、テキストを青で出力します:

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に色が追加されている例はどこにも見つかりません。

76
Jernej Jerin

パーツをきれいに分離するのではなく、一緒に混ぜています。

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

基本的に、フォーマットに固定のものを、パラメーターに可変のものを入れます。

65
geekosaur

旧式の端末コードを使用するのではなく、次の代替案を提案できますか。より読みやすいコードを提供するだけでなく、元々意図したとおりに色情報を書式指定子から分離しておくこともできます。

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

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

私の答えを参照してください [〜#〜] here [〜#〜] 追加の色について

154
SiegeX

これは私のために働く:

_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
_
24
Vlad

これは、端末で異なる色を取得するための小さなプログラムです。

#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;
}
17
Kritpal Singh

これは、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";
12
Arian Acosta

色付きのシェル出力の印刷にこのcコードを使用します。コードは this 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;
}
3
Jonny Schubert

man printf.1の下部に「...お使いのシェルにはprintf...の独自のバージョンがある場合があります」というメモがあります。この質問にはbashのタグが付けられていますが、可能な場合は、anyShellに移植可能なスクリプトを記述しようとします。 dashは通常、移植性のための適切な最小ベースラインです。したがって、ここでの答えはbashdash、およびzshで機能します。これら3でスクリプトが機能する場合、ほぼどこにでも移植できる可能性が最も高いです。

printfdashの最新の実装[1] ANSIエスケープ文字%sを使用して\e書式指定子を指定した場合、出力を色付けしません-but、書式指定子%bと8進数の\033(ASCII ESCと同等)を組み合わせると、仕事が完了します。外れ値についてはコメントしてください。 ASCII 8進数サブセットを最低限使用するためにprintfを実装しました。

「printfでの色の使用」という質問のタイトルに、書式設定を設定する最もportableの方法は、printf%b書式指定子を結合することです( 8進エスケープ\033を使用した以前の answer @Vladで参照)。


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

... 2行目の「青」は青です。

OPの%-6s形式指定子は、制御文字シーケンスの開始と終了の間の形式文字列の中間にあります。


[1]参照: man dash セクション "Builtins" :: "printf" :: "Format"

2
AaronDanielson