web-dev-qa-db-ja.com

画面の中央にテキストファイルの行を1つずつ表示する方法を探しています

テキストファイルを取得し、特定の文字幅で各行を1つずつ画面の中央に配置する方法を探しています。

ちょっとしたスライドショーのようなものです。ユーザーがキーを押すまで最初の行を表示し、すべての行が表示されるまで次の行を表示します。

これをbashで行う基本的な方法はあると思いますが、まだ答えを見つけていません。

8
ak0000

そんな感じ:

_#!/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
_

Shebang です。さらに、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_を使用して逆参照されます。この関数は最初に画面をクリアし、次に画面の上部からlines/2だけ下に移動して画面の中央に到達し、次に here から借りた方法を使用して中央の線を印刷します。

これは、ユーザーから渡された入力ファイルを読み取り、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の詳細については、_help read_を参照してください。 stdinがすでにファイルをポイントしているため、/ dev/ttyから直接読み取ることもできます。readに/ dev/ttyから読み取るように指示しなかった場合、スクリプトはファイルからすべての行を非常にすばやく出力し、すぐに終了しますユーザーがキーを押すのを待たずに。

12

あなたは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行ずつ表示されます。前後に移動でき、最後の行の後で終了します。

5
Quasímodo

以下は、簡単で汚いワンライナーです。

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コマンドを使用すると、ユーザーはページをめくることができます。

1
Digital Trauma