bashスクリプトの一部のキーワードのみをどのように色付けしますか?


10

ユニットテストコードを実行しています。ユニットテストコードは通常のテキストを出力します。テキストが多いので、ユーザーにとって重要なキーワードを強調したいと思います。

この場合のキーワードは「PASS」と「FAIL」です。

「合格」を緑色に、「不合格」を赤色にするにはどうすればよいですか?


合格したテストのstdout / stderrを抑制し、失敗したテストのstdout / stderrのみを出力することを考えましたか?PHPUnitはこれを行うか、またはこれを行うように構成可能です。このアプローチはYMMVで非常にうまく機能することがわかりました。
クレイトンスタンレー

回答:


8

supercat あなたが探していることをするようです。

パッケージ:supercat
Description-en:端末とHTMLのテキストに色を付けるプログラム
 Supercatは、正規のマッチングに基づいてテキストを色付けするプログラムです
 式/文字列/文字。SupercatはHTML出力もサポートします
 標準のASCIIテキストとして。一部のテキスト色付けプログラムとは異なり、
 Supercatは、プログラマーである必要はありません。
 色付けルールを作成します。
ホームページ:http://supercat.nosredna.net/

コマンドラインで何を彩色するかを伝える方法はないようです。設定ファイルを指定する必要があります。

パターンに一致するテキストを強調表示する「hilite」または「hl」と呼ばれるプログラムがあったことを思い出しているようです(のようgrep --colourですが、一致しない行も表示されています)。ただし、検索しても見つかりませんでした。

最後に、GNU grepを使用してパターンを強調表示することができますが、使用できる色は1つだけです(つまり、PASSを緑で、FAILを赤で使用することはできません。どちらも同じ色で強調表示されます)。

次のようなものにデータをパイプします。

egrep --color "\b(PASS|FAIL)\b|$"

この例ではegrep(別名grep -E)を使用していますが、-G基本的な正規表現、-F固定文字列、-PPCREも機能します。

すべての一致が強調表示されます。デフォルトは赤、またはGREP_COLOR環境変数を設定します。

この作業の鍵|$は、パターンの最後が行末と一致する(つまり、すべての行が一致する)ため、すべての行が表示される(ただし、色付けされない)ことです。

\bそれは例えばFAILではなく、失敗を一致するように、ワード境界マーカーです。それらは必要ないので、部分的な単語と一致させたい場合は削除してください。

これが私が昨日書いたsupercatのラッパースクリプトの例です。動作しますが、それを書いているときに、supercatには大文字と小文字を区別しない検索のオプションがないことがわかりました。IMO、これはプログラムの有用性を著しく低下させます。ただし、 '-i'オプションを記述する必要がないため、スクリプトが大幅に簡略化されました。

#! /bin/bash 

# Requires: tempfile from debian-utils, getopt from util-linux, and supercat

SCRIPTNAME=$(basename $0)
CFGFILE=$(tempfile -p spc)

usage() {
  cat <<__EOF__
Highlight regexp patterns found on stdin or files specified on command
line with specified colours.

Usage: $SCRIPTNAME [ --colour "pattern" ...] [FILE]

Options:

        -k,--black   regexp
        -r,--red     regexp
        -g,--green   regexp
        -y,--yellow  regexp
        -b,--blue    regexp
        -m,--magenta regexp
        -c,--cyan    regexp
        -w,--white   regexp

Example:

    run-script.sh | $SCRIPTNAME --green PASS --red FAIL

__EOF__
  exit 0
}


# Format definition from the spc man page:
#1234567890123456789012345678901234567890123456789012345
#HTML Color Name      Col A N T RE / String / Characters
FMT="%-20s %3s %1s %1s %1s (%s)\n"

add_color_to_config() {
  COLOR="$1"
  PATTERN="$2"

  printf "$FMT" "$COLOR" "$COLOR" - 0 r "$PATTERN" >> "$CFGFILE"
}


# uses the "getopt" program from util-linux, which supports long
# options. The "getopts" built-in to bash does not.
TEMP=$(getopt \
       -o 'hk:r:g:y:b:m:c:w:' \
       -l 'help,black:,red:,green:,yellow:,blue:,magenta:,cyan:,white:' \
       -n "$0" -- "$@")

if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi

eval set -- "$TEMP"

while true ; do
    case "$1" in
        -k|--bla*)       add_color_to_config blk "$2" ; shift 2 ;;
        -r|--red)        add_color_to_config red "$2" ; shift 2 ;;
        -g|--gre*)       add_color_to_config grn "$2" ; shift 2 ;;
        -y|--yel*)       add_color_to_config yel "$2" ; shift 2 ;;
        -b|--blu*)       add_color_to_config blu "$2" ; shift 2 ;;
        -m|--mag*)       add_color_to_config mag "$2" ; shift 2 ;;
        -c|--cya*)       add_color_to_config cya "$2" ; shift 2 ;;
        -w|--whi*)       add_color_to_config whi "$2" ; shift 2 ;;

        -h|--hel*)       usage ; exit 0 ;;

        --)         shift ; break ;;

        *)          echo 'Unknown option!' ; exit 1 ;;
    esac
done

spc -R -c "$CFGFILE" "$@"
rm -f "$CFGFILE"

1
ところで、使用したsupercat場合は、投稿したスクリプトを変更して、コマンドライン引数に基づいて一時設定ファイルを生成し、を呼び出すことができますspc -c /path/to/your/temp/config。これにより、コマンドラインでさまざまなパターンにさまざまな色を簡単に指定できます。
cas

また、私はそれを行う簡単なラッパースクリプトを作成しました。私は今仕事に行く必要がありますが、私はそれを片付け、いくつかのコメントなどを追加し、今日後で投稿します。
cas

5

以下は、正規表現パターンを色付けするための汎用スクリプトです(おそらくいくつかのレタッチが必要です)。

#! /bin/bash

color_to_num () {
  case $1 in
    black)  echo 0;;
    red)    echo 1;;
    green)  echo 2;;
    yellow) echo 3;;
    blue)   echo 4;;
    purple) echo 5;;
    cyan)   echo 6;;
    white)  echo 7;;
    *)      echo 0;;
  esac
}

# default values for foreground and background colors
bg=
fg=
bold="$(tput bold)"
italics=""
boundary=""

while getopts f:b:sli option; do
  case "$option" in
    f) fg="$OPTARG";;
    b) bg="$OPTARG";;
    s) bold="";;
    l) boundary=".*";;
    i) italics="$(tput sitm)";;
  esac
done

shift $(($OPTIND - 1))

pattern="$*"

if [ -n "$fg" ]; then
  fg=$(tput setaf $(color_to_num $fg))
fi
if [ -n "$bg" ]; then
  bg=$(tput setab $(color_to_num $bg))
fi

if [ -z "$fg$bg" ]; then
  fg=$(tput smso)
fi

sed "s/${boundary}${pattern}${boundary}/${bold}${italics}${fg}${bg}&$(tput sgr0)/g"

名前を付けてhilite.sh、次のように使用します。

$ ./BIN_PROGRAM | hilite.sh -f green PASS | hilite.sh -f red FAIL

$ # Here is an example one liner
$ echo -e "line 1: PASS\nline 2: FAIL" | hilite.sh -f green PASS | hilite.sh -f red FAIL

community wiki私の解決策が機能しないので、私はこれを作りました。
Trevor Boyd Smith

テストする簡単な方法は、「PASS」と「FAIL」というキーワードを含むテキストをエコーする別のスクリプトを作成することです。その後、このスクリプトによって呼び出されます。
Trevor Boyd Smith

トピックから少し外れていますが、$BINvia の出力evalをコマンド置換に解析することは、おそらく壊れやすく、扱いにくく、非常に危険であることを指摘しなければなりません。STDOUTはストリームであり、通常はストリームのようなツールで処理されることを意図しています。ストリーム全体を変数にキャプチャしようとするのは、あまり効率的ではありません。また、eval危険なほど強力です。そのため、実際に何をしているかを理解している場合にのみ使用してください。
jw013 2012

スクリプトを有効なスクリプトに置き換えました。
アンガス

@angus、本当に本当に素晴らしい、印象的なスクリプトIMO。
Trevor Boyd Smith、

3

文字列が有効な構文であることを(エスケープによって)確認する必要があるため、置換などの式に任意の文字列(tput出力など)を埋め込むことsedは問題がありsedます。awk代わりに使用します。例として:

{ echo line 1: PASS; echo line 2: FAIL; } | 
    awk -v "red=$(tput setaf 1)" -v "green=$(tput setaf 2)" \
        -v "reset=$(tput sgr0)" '
    { for (i = 1; i <= NF; i++) {
           if ($i == "FAIL") printf "%s", red "FAIL" reset;
           else if ($i == "PASS") printf "%s", green "PASS" reset;
           else printf "%s", $i

           if (i == NF) printf "%s", ORS
           else printf "%s", OFS 
      }}'

重要なのは、tputシーケンスをawk変数に割り当てること-vです。ここではオプションを使用して行います。


私はあなたのプログラムを実行しました、そしてそれは必要なことをします。フザー!しかし、残念ながら私はawkの第一人者ではないので、何が起こっているのかを理解するのは困難です。間違っている箇所を修正してください。新しい行ごとにawkが実行されますか?awkソースコードのforループは、「行のすべてのトークン」を実行していますか?その後、各トークンを処理しますか?
Trevor Boyd Smith

Awkはフィールドとレコードの観点から考えています。デフォルトでは、レコードはテキスト行であり、フィールドは非空白文字です。awkスクリプトは、ブロックのセット(の間のもので構成されて{}トップレベルで)。各ブロックは条件に関連付けられています-上記の私の投稿では、すべての入力行に対して無条件に動作したいので何もありません。Awkは、ファイルまたは標準入力(この場合はSTDIN b / cであり、ファイル名は指定されていません)からレコードを読み取り、それらをすべてのブロックと順番に照合して、条件が一致した場合にレコードでブロックを実行します。
jw013

2

printfを使用します。

printf "\e[%sm%s\e[00m\n" <some_number> <text_in_colour>

例えば。

printf "\e[%sm%s\e[00m\n" 32 yodle

最後\nは改行文字を追加します。

次のようなtryの可能な値を確認するには:

for i in {0..9} {30..38} {90..98} {100..108};
do
    printf "%d:\e[%sm%s\e[00m\n" $i "$i" yodle;
done

色に加えて、数字を組み合わせることで、太字や下線、色付きの背景を持つ色付きのテキストなどの修飾子を追加できます。下線が引かれ、使用中に取り消し線が引かれた灰色の背景を持つ青色のテキストを作成するには:

printf "\e[%sm%s\e[00m\n" "4;9;34;107" yodle

乾杯、

/ B2S


2

BASHスクリプトとをインストールしてよろしければackhhlighterパッケージには便利なデフォルトの色と簡単なインターフェースhttps://github.com/paoloantinori/hhighlighterがあります

ハイライトの例

このように使用して、FAIL次の文字で始まる行を強調表示できます。

h -i 'FAIL.*'

またはそれを含むFAIL

h -i '.*FAIL.*'

またはさまざまな一般的なログエントリ:

h -i '.*FAIL.*' '.*PASS.*' '.*WARN.*'

そしてもちろん、単純なgrepを使用した単色(赤)の場合:

$ printf 'Pass: good job\nFail: bad job\n' | grep -Ei --colour=auto '^|fail.*'

^すべての行に一致しますが、特別なマッチャーであり、行全体を出力します。強調表示される式は、の後に定義されます|。で区切られている限り、さらに式を追加できます|

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.