web-dev-qa-db-ja.com

printfの「%* s」パディング形式に影響を与えることなく、端末のフォントの色を変更することは可能ですか?

Bashスクリプトに関数_message_offset_があります。これは、bashスクリプトのステータスを出力するために使用されます。
つまりあなたはそれにメッセージとステータスを渡すことをこのように呼ぶでしょう

_message_offset "install font library" "[   OK   ]" 
_

printfの_%*s_形式を使用して、常に_[ OK ]_の右端の文字を80列幅に設定する端末に出力されます。出力は

_install font library                              [   OK   ]
update configuration file on server               [   ERR  ]
                                                           ^
                                                           |
                                                      always
                                                        at 80
_

echoが使用された場合、出力は次のようになります。

_install font library                 [   OK   ]
update configuration file on server               [   ERR  ]
_

コード:

_#!/usr/bin/env bash

function message_offset() {

    local message="$1"
    local status="$2"

    # compensate for the message length by reducing the offset 
    # by the length of the message, 
    (( offset = 80 - ${#message} ))

    # add a $(tput sgr0) to the end to "exit attributes" whether a color was
    # set or not
    printf "%s%*s%s" "${message}" 80 "$status" "$(tput sgr0)"

}
_

tputを使用して文字列にいくつかのカラーシーケンスを追加しようとするまで、つまり「[ERR]」を赤にするまで、これはすべて問題なく機能します。
_printf "%*s"_フォーマットはオフセットを設定するときにtput文字シーケンスをカウントしているようですので、このような関数を呼び出すと

_message_offset "update configuration file on server"  "$(tput setaf 1)[   ERR  ]"
_

出力は次のようになります。

_install font library                              [   OK   ]
update configuration file on server          [   ERR  ]
_

_printf "%*s"_は、この文字列にはすべての_"[ ERR ]"_文字と"$(tput setaf 1)文字が含まれていると言っているので、明らかに"$(tput setaf 1)文字は出力されないので、ドン実際にはパディングには影響しません。
「ステータス」メッセージに色を追加したり、tputスタイルのカラーシーケンスを使用したりする方法はありますか?

7
the_velour_fog

あなたはこれを本来よりもずっと複雑にしている。 _$message_で位置合わせを処理でき、ANSIシーケンスの幅は気にしません。

_#! /usr/bin/env bash

message() {
    [ x"$2" = xOK ] && color=2 || color=1
    let offset=$(tput cols)-4-${#2}
    printf "%-*s[ %s%s%s ]\n" $offset "$1" "$(tput setaf "$color")"  "$2" "$(tput sgr0)"
}  

message "install font library" "OK"
message "update configuration file on server" "ERR"
_

編集:ほとんどのprintf(1)実装は、マルチバイト文字セットの長さの計算にうまく対応していないことに注意してください。したがって、UTF-8でアクセント付き文字を使用してメッセージを印刷する場合は、別のアプローチが必要になる場合があります。 肩をすくめる

8
Satō Katsura

簡単なアプローチは、すべてを色付けすることです整列されています

一言で言えば、あなたは必要です

  • 文字列を色で色付けする関数(またはより適切な外部スクリプト)(たとえば、Perlのs,$regex,$color$&$resetcolor,gi

  • そしてあなたはそれをあなたは印刷をしました。カラーエスケープコードは、そのように配置を変更しません。

例:colors引数をとる「colorize」という名前のスクリプトを作成し、その後にその色で色付けされる正規表現を作成したとします。例colorize -blue 'regex1' -green 'regex2'必要に応じて呼び出します:

 { code
   that
  formats and display things
 } | colorize -red 'ERR' -green 'OK'

それ自体をスクリプトとして使用すると、たとえば次のように、どこでも使用できます。

 df -h | colorize -red '[890].%'
1
Olivier Dulac