Bash
シェル芸
tput
cols
hrタグ

シェルで<HR>(水平線)を表現する方法各種

Horizontal Line にひかれて

HTMLでいう<HR>タグのように、横線/区切り線をシェルスクリプトで表現する各種方法です。

fix / dynamic

固定長か可変長かの大きく2通りの方法があります。つまり、①幅(線の長さ)を指定するタイプと②画面幅を取得してそのぶんを繰り返すタイプがあります。

注意点

tputが使える環境ではタイプ②のターミナルの横幅いっぱいの水平線が引けますが、tputが使えない環境(環境変数 $TREM 値が空)の場合はtput: No value for $TERM and no -T specifiedエラーになるのでif [ -n "${TERM}" ]; then width=$(tput cols); else width=20; fiといった分岐が必要になります。

// Set width
if [ -n "${TERM}" ];
  then SCREEN_WIDTH=$(tput cols);
  else SCREEN_WIDTH=20;
fi

// Draw HR function
echo_hr(){
  printf -v _hr "%*s" ${SCREEN_WIDTH} && echo ${_hr// /${1--}}
}

// Usage
echo_hr

タイプ②の場合、基本的にどれも tput cols でターミナルの横幅を取得して画面横幅いっぱいに描画するのですが、結果は同じでもその過程で表現が違うのが面白いです。

指定した長さの水平線

もっとも単純な方法

echo --------------------
printf '%s\n' --------------------

繰り返し処理で表現する方法

forループで表現する

for ((x = 0; x < 20; x++)); do
  printf %s -
done
echo

yesコマンドで表現する

yes = | head --lines=20 | tr --delete '\n' ; echo

スペースをハイフンに置換して表現する

printf '%20s\n' | tr ' ' -
printf -v res %20s
printf '%s\n' "${res// /-}"

tput colsを使ったターミナル画面いっぱいの水平線

文字の置換を使った表現方法

printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -

パラメーター指定の表現方法

hr="[WARNING]-[WARNING]-[WARNING]-[WARNING]-[WARNING]-[WARNING]-[WARNING]-[WARNING]-[WARNING]-[WARNING]-[WARNING]-"
printf '%s\n' "${hr:0:${COLUMNS:-$(tput cols)}}"

関数を使ってハイフンでなく直線で水平線を引く方法

hr() {
  local start=$'\e(0' end=$'\e(B' line='qqqqqqqqqqqqqqqq'
  local cols=${COLUMNS:-$(tput cols)}
  while ((${#line} < cols)); do line+="$line"; done
  printf '%s%s%s\n' "$start" "${line:0:cols}" "$end"
}

hr

関数を使って引数で渡された文字で水平線を引く方法

rule () {
  printf -v _hr "%*s" $(tput cols) && echo ${_hr// /${1--}}
}

# イコールを横幅いっぱいに引く
rule =

# 骸骨の文字絵を横幅いっぱいに引く
rule `echo -e "\\xE2\\x98\\xA0"`

printfのマニアックな使い方をした表現方法

printf '%.0s-' {1..20}; echo
eval printf %.0s- '{1..'"${COLUMNS:-$(tput cols)}"\}; echo
eval printf %.1s '-{1..'"${COLUMNS:-$(tput cols)}"\}; echo
_=- command eval printf %s '"${_[0]"{0..'"${COLUMNS:-$(tput cols)}"'}"}"'; echo

参考文献