ナノテキストエディタでは、選択内容をコマンドとして送信でき、しばしばテキストを中央に配置する必要があるため、次のコードを考えました。
center() {
str=$1
# Strip leading and trailing whitespace from the string
str=$(echo "$str" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
str_len=${#str}
margin=$(((80 - str_len) / 2))
printf "%*s%s%*s\n" $margin "" "$str" $margin ""
}
しかし、私はスクリプトについてよく知らないので、このコードを改善する方法を知りたいです。
Bashソリューションに接続するのはなぜですか?私はこのシェルを使用しません。ただshで実行したいです。
答え1
シェルを使用していると仮定するとbash
(そうでない場合はこの回答の最後を参照)、bash
標準変数の拡張および拡張ワイルドカードパターン(1つ以上の空白に似た文字と一致する)を使用して、文字列からサイドスペースをより効率的に削除できます。str
+([[:space:]])
shopt -s extglob
str=$1
str=${str##+([[:space:]])} # strip at start
str=${str%%+([[:space:]])} # strip at end
(で与えられた列に右揃えで印刷したい。勝つ+S)/2勝つは端子の幅です(出力によってはtput cols
、しかし使用することもできます$COLUMNS
)。S文字列の長さです(${#str}
)。
printf '%*s\n' "$(( ( $(tput cols) + ${#str} ) / 2 ))" "$str"
機能:
center () (
shopt -s extglob
str=$1
str=${str##+([[:space:]])}
str=${str%%+([[:space:]])}
printf '%*s\n' "$(( ( $(tput cols) + ${#str} ) / 2 ))" "$str"
)
関数の本体はサブシェルです。これにより、extglob
シェルオプションの設定は呼び出しシェルにあふれません。
依存関係なしextglob
(すべてに適用sh
):
center () {
str=$(printf '%s\n' "$1" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
printf '%*s\n' "$(( ( $(tput cols) + ${#str} ) / 2 ))" "$str"
}
静的80列幅でフォーマットするには、$(tput cols)
に置き換えます。80
答え2
間に複数のスペースが連結されていない場合は、次のコマンドを使用してトリミングを簡素化できます。str=$(echo $1)
center () {
str=$(echo $1)
len=${#str}
margin=$((($COLUMNS - len) / 2))
printf "%${margin}s%s\n" " " "$str"
}
後にスペースを追加する必要はありません$str
。