数値ベースのシェーディングパラメータ

数値ベースのシェーディングパラメータ

bash関数に渡された複数の文字列引数があり、各引数は別々の行に印刷されます。

warn最初のパラメータから赤で印刷された行数だけ値が表示されるようにコードを変更したいと思います${@}

rge='^[0-9]+$'
if [[ -v warn && "$warn" == "1" ]]; then
  printf '%s\n' ${red}"$1"${sgr}  # first line red
  printf '%s\n' "${@:2}"          # remaining, uncoloured
elif [[ -v warn && "$warn" =~ $rge ]]; then
  printf '%s\n' ${red}"$@"${sgr}  # all lines red
fi

最初の試みで

elif [[ -v warn && "$warn" =~ $rge ]]; then
  argc=$#
  argv=("$@")
  printf "%s\n" "argc: $argc"
  for (( j=0; j<warn; j++ )); do
    printf '%s\n' ${red}"${argv[j]}"${sgr}
  done

  #printf '%s\n' ${red}"$@"${sgr}  # all lines red
fi

ベストアンサー1

入力行番号など、さまざまな条件に基づいてさまざまなタスクを実行する方法を既に知っている既存のツールを活用してください。たとえば、awk、sed、Perl、Pythonなどがあります。

ところでshでもできますが、なぜそうでしょうか?シェルループは、ほぼ常にあらゆる形式のテキスト処理を実行する最悪の方法です。

たとえば、以下では、シェルを使用して環境変数を設定し、次に色を強調表示しますawk(a)シェルの行数を計算し、b)読み取りループ中にシェルを使用して素早く、厄介な、簡単で簡単な操作を実行する防止しますawk

colourise() {
  # colourise all (default) or the first N lines of stdin
  # where N is the optional first argument to the function.

  # check if arg is empty or numeric
  [ -z "$1" ] || [[ "$1" =~ ^[0-9]+$ ]] \
    || echo "optional arg must be numeric if supplied" && exit 1

  local colour="$(tput setaf 9)"
  local sgr0="$(tput sgr0)"
  awk -v c="$colour" -v s="$sgr0" -v w="$1" \
    '(NR <= w || w == "") {print c $0 s; next}1'
}

ところで、awkスクリプトから直接カラーコードとsgrコードをハードコードできます。その後、 "$1" の値を awk に渡します (またはexport warn="$1"シェルで awk で ENVIRON["warn"] を使用)。ただし、awkには機能がないため、tputこれを手動で実行する必要があります。たとえば、以下は、vt100、ansi、xtermなどのほとんどの端末で動作します。

colourise() {
  local warn="$1"
  export warn

  awk 'BEGIN {c="\033[91m"; s="\033[m\017"; w=ENVIRON["warn"]}
       (NR <= w || w == "") {print c $0 s; next}1'
}

または(ターミナルのハードコーディングエスケープシーケンスが悪いので):

colourise() {
  local warn="$1"
  local colour="$(tput setaf 9)"
  local sgr0="$(tput sgr0)"
  export warn colour sgr0

  awk 'BEGIN {c=ENVIRON["colour"]; s=ENVIRON["sgr0"]; w=ENVIRON["warn"]}
       (NR <= w || w == "") {print c $0 s; next}1'
}

次に、必要なものをcolourise関数にパイプします。例えば

# colourise first three lines of an array
printf "%s\n" "${array[@]}" | colourise 3

# colourise all lines of head
head filename | colourise

# colourise only the first line of the output from several
# commands.   use a compound command {} or a sub-shell ()
# this does not colourise the first line of each command separately,
# only the first line of the combined output.
{
command1
command2
command3
} | colourise 1

おすすめ記事