正規表現に一致する文字列入力に基づいて色を指定する Bash 関数

正規表現に一致する文字列入力に基づいて色を指定する Bash 関数

Bashスクリプトで印刷する複数行の文字列があります。

docstring="
 Headings
  -H, -H CNT, -H=CNT, -HCNT, --heading CNT, --heading=CNT

 Warnings
  -W, -W CNT, -W=CNT, -WCNT, --warning CNT, --warning=CNT

 Errors
  -E, -E CNT, -E=CNT, -ECNT, --error CNT, --error=CNT"

echo "$docstring"

-この文字列を使用して、or in colorで始まる行を印刷する関数を作成したいと思います{-

したがって、次の色が割り当てられます。

-H, -H CNT, -H=CNT, -HCNT, --heading CNT, --heading=CNT
-W, -W CNT, -W=CNT, -WCNT, --warning CNT, --warning=CNT
-E, -E CNT, -E=CNT, -ECNT, --error CNT, --error=CNT

答え1

GNUの使い方、文字列に、\または文字が含まれていないとします。`"$

printred(){ 
    sed -E 's/^ *\{?-.*/tput setaf 1;printf "%s" "&";tput sgr0/e' <<< "$@"
}

使用法:

printred "$docstring"

別の色を選択するには、以下を確認してください。

for i in {0..7}; do
    tput setaf "$i"
    echo "tput setaf $i"
    tput sgr0
done

指示:

CGIスクリプトとして使用しないでプライベートにしてください。 Stephane Chazelasが指摘したように、任意のコマンドを実行できるからです。これは信頼できる環境で使用するためのものです。または、入力文字列を削除するフィルタを作成します。

答え2

GNUとの実装grepまたは互換性:

grep --color -Ee '^\s*\{?-.*' -e '^' <<< "$docstring"

これはgrep、任意の数の空白文字で始まる行、その後にオプションの文字、任意の数の文字、または行の先頭が続き、出力が端末装置に到達するたびに(表示されると仮定)一致する内容をpingする行{です。-。これらのエスケープシーケンスを解釈する色が端末に表示されます。--color=always出力が端末デバイスに送信されない場合でも、色を追加するように変更できます。

使用されるプロパティと色(デフォルトでは太字の赤)は、$GREP_COLORS環境変数(以前)によって$GREP_COLOR制御されます。

grepたとえば、添付の内線通貨を太字、前景は黄色、背景は赤にGREP_COLORS='mt=1;41;33' grep...します。mt

printred一致する行を赤で印刷する関数は次のとおりです。

println() { # prints each of its arguments on separate lines
  [ "$#" -eq 0 ] || printf '%s\n' "$@"
}
printred() {
  println "$@" |
    GREP_COLORS='mt=31' grep --color -Ee '^\s*\{?-.*' -e '^'
}

GNUismsに依存せずにこれらの行を強調表示する別の方法は、一致する行のsed周りにANSIエスケープシーケンスを追加することです。

ESC=$(printf '\33')
printred() {
  if [ -t 1 ]; then
    println "$@" |
      sed "s/^[[:space:]]*{\{0,1\}-.*/${ESC}[31m&${ESC}[m"
  else
    println "$@"
}

またはperl代わりにsed

perl -pe 's/^\s*\{?-.*/\e[31m$&\e[m/'

関連情報