テキスト ファイルを取得して、各行を特定の文字幅で 1 行ずつ画面の中央に配置する方法を探しています。
必要最低限のスライド ショーのようなもので、たとえば、ユーザーがキーを押すまで最初の行が表示され、その後、すべての行が表示されるまで次の行が表示されます。
bash でこれを行う基本的な方法があると思われますが、まだ答えは見つかっていません。
答え1
そんな感じ:
#!/usr/bin/env bash
if [ ! "$#" -eq 1 ]
then
printf "Usage: %s <file>\n" "$0" >&2
exit 1
fi
file="$1"
display_center(){
clear
columns="$(tput cols)"
lines="$(tput lines)"
down=$((lines / 2))
printf '\n%.0s' $(seq 1 $down)
printf "%*s\n" $(( (${#1} + columns) / 2)) "$1"
}
while IFS= read -r line
do
display_center "$line"
read -n 1 -s -r </dev/tty
done < "$file"
名前を付けcentered.sh
て次のように使用します:
./centered.sh centered.sh
指定されたファイルの各行を印刷します。任意のキーを押すと次の行が表示されます。まだ十分にテストされていないため、注意して使用してください。また、常に画面の中央から行が印刷されるため、長い行は下部に表示されることに注意してください。
最初の行:
#!/usr/bin/env bash
はシバンさらに、私env
はその特徴私は Bash を避けて POSIX シェルでこのスクリプトを書こうとしましたが、特にread
問題が多かったため断念しました。Bash はどこにでもあるように見えるかもしれませんが、たとえば BSD や Busybox を搭載した小さな組み込みシステムなど、どこにでもデフォルトでプリセットされているわけではないことに注意してください。
この部分では:
if [ ! "$#" -eq 1 ]
then
printf "Usage: %s <file>\n" "$0" >&2
exit 1
fi
ユーザーが正確に 1 つのパラメータを指定したかどうかを確認し、指定しなかった場合は使用方法情報を標準エラーに出力し、親プロセスにエラーを意味する 1 を返します。
ここ
file="$1"
file
ユーザーが渡したファイル名パラメータを後で使用する変数に割り当てます 。
これは実際に中央揃えのテキストを印刷する関数です。
display_center(){
clear
columns="$(tput cols)"
lines="$(tput lines)"
down=$((lines / 2))
printf '\n%.0s' $(seq 1 $down)
printf "%*s\n" $(( (${#1} + columns) / 2)) "$1"
}
Bashには関数のプロトタイプがないので、関数がいくつのパラメータを取るかを事前に知ることはできません。その関数は、印刷する行である1つのパラメータのみを取り、次の方法で逆参照されます。$1
この関数は、最初に画面をクリアし、次に画面の上から行/2だけ下に移動して画面の中央に到達し、次に私が借りた方法を使用して中央の行を印刷します。ここ。
display_center()
これは、ユーザーが渡した入力ファイルを読み取り、関数を呼び出すループです 。
while IFS= read -r line
do
display_center "$line"
read -n 1 -s -r </dev/tty
done < "$file"
read
は-n 1
、1文字だけを読み取り、-s
端末からの入力をエコーしないようにし-r
、バックスラッシュのマングルを防ぐの詳細については、 を参照してくださいread
。stdinhelp read
がすでにファイルを指しているため、/dev/tty から直接読み取ります。/dev/ttyread
から読み取るように指示しなかった場合、スクリプトはファイルのすべての行を非常に速く印刷し、ユーザーがキーを押すのを待たずにすぐに終了します。
答え2
パッケージを使用して実行できますdialog
:
file=lorem #Path to the file to be displayed
ln=1 #Current line number to be displayed
nlines=$(wc -l "$file"|cut -f1 -d" ") #Total number of lines of file
while [ "$ln" -le "$nlines" ]; do
line=$(sed -n "$ln p" "$file") #sed gets current line
if dialog --yes-label Previous --no-label Next \
--default-button no --yesno "$line" 5 100; then
ln=$((ln-1))
else
ln=$((ln+1))
fi
done
これはテキストベースのプレゼンテーション (「必要最低限のスライド ショー」を真剣に考えました) で、X セッションは不要で、一度に 1 行ずつ表示されます。前後に移動でき、最後の行が表示されたら終了します。
答え3
簡単にまとめると次のようになります。
sed ':a;s/^.\{1,77\}$/ &/;ta;s/\( *\)\1/\1/; s/.*/\n\n\n\n\n\n\n\n\n\n\n&\n\n\n\n\n\n\n\n\n\n\n/' < input.txt | more
これは 80x24 のターミナル ウィンドウを想定しています。このsed
コマンドはテキストの各行を中央揃えにし、垂直に中央揃えするのに十分な先頭と末尾の改行を追加します。このmore
コマンドにより、ユーザーはページを移動できます。