web-dev-qa-db-ja.com

bashでテキストを正当化して中央揃えする方法は?

初心者はこちら。テキストを中央揃えして正当化するbashスクリプトを探しています。私のスクリプトは1行のテキストでしか機能しません。どのように改善しますか?

#!/bin/bash
COLS=$(tput cols)
while true; do
    clear
    echo -n "Type text "
    read text
    echo
    echo "Menu"
    echo "1) Right justify  "
    echo "2) Center "
    echo "3) Exit "
    echo
    echo -n "Choose [1-3]: "
    read opt
    echo
    case $opt in
        1) printf "%*s\n" $COLS "$text"
           break
        ;;
        2) printf "%*s\n" $[$COLS/2] "$text"
           break
        ;;      
        3) break
        ;;
        *)
        echo "Error. Press [1-3]"
        break
        ;;
    esac
done
6
Edward

あなたが発見したように、_$COLUMNS_はインタラクティブな_-i_シェルでのみ役立つため、代わりにcolumns="$(tput cols)"を使用します。

私が持っている唯一の問題は、以下の行にあります。テキストを中央揃えしません。
_printf "%*s\n" $[$COLS/2] "$text"_

作業を拡張して、ここに中央揃えのテキストを(ファイルから)表示する関数があります。スクリプト内で呼び出すには、_display_center "file.txt"_を使用します

_display_center(){
    columns="$(tput cols)"
    while IFS= read -r line; do
        printf "%*s\n" $(( (${#line} + columns) / 2)) "$line"
    done < "$1"
}
_

_${#line}_(_wc -m_と同様)を使用して、行の文字数を数えることに注意してください。カラー/フォーマットなしでプレーンテキストのみを表示する必要がある限り、これは問題なく機能します。

これは、printfの同じ実装を使用して(ファイルから)右揃えのテキストを表示する関数です。

_display_right(){
    columns="$(tput cols)"
    while IFS= read -r line; do
        printf "%*s\n" $columns "$line"
    done < "$1"
}
_

Tputとechoでも同様のことができますが、以下の例はそれほど堅牢ではありません(つまり、長い文字列では失敗します)。

_row=0
col=$(( ($(tput cols) - ${#text}) / 2))
tput clear
tput cup $row $col
echo "$text"
_

また、dialogまたはselectを使用してメニューを生成することを検討してください。スクリプトが大幅にクリーンになります。
http://bash.cyberciti.biz/guide/Select_loop
https://serverfault.com/questions/144939/multi-select-menu-in-bash-script

6
Six
#!/usr/bin/awk -f
{
  z = 92 - length
  y = int(z / 2)
  x = z - y
  printf "%*s%s%*s\n", x, "", $0, y, ""
}

入力

ハローワールド
アルファブラボーチャーリーデルタ

出力

 hello world 
アルファブラボーチャーリーデルタ
3
Steven Penny

行の内容を破壊せずに?

このソリューションは、カーソルが現在置かれている行の中央にテキストを配置しますなし境界の周りにスペースを印刷します。現在行に印刷されているものを破壊せずにテキストを中央揃えにしたい場合に便利です。

通知:この例が機能するには、シェルがANSIエスケープシーケンスをサポートしている必要があります。

#!/bin/bash
print_center(){
    local x
    local y
    text="$*"
    x=$(( ($(tput cols) - ${#text}) / 2))
    echo -ne "\E[6n";read -sdR y; y=$(echo -ne "${y#*[}" | cut -d';' -f1)
    echo -ne "\033[${y};${x}f$*"
}

# main()

# clear the screen, put the cursor at line 10, and set the text color
# to light blue.
echo -ne "\\033[2J\033[10;1f\e[94m"

# do it!
print_center 'A big blue title!'

カーソルは「タイトル」の最後に残ります!この例では。別のANSIシーケンスを使用して、必要に応じてカーソルを再配置します。


長所

  • SSHで動作
  • 中央揃えの問題なしでデバイスバッファーのサイズを変更できます(動的)
  • 行の内容を破棄しません
  • アスキーゲーム/アニメーションフレンドリー。

短所

  • 端末がANSIエスケープシーケンスをサポートしていない場合は機能しません
  • ログ出力のローリング用ではありません。
  • Bashに依存

1
Robert Smith

私もbashスクリプトのテキストを揃えるのに苦労していたので、解決策を見つけました:

# echo -e "\t Hello World!"
0