Suche nach einer Möglichkeit, Zeilen einer Textdatei einzeln zentriert auf dem Bildschirm anzuzeigen

Suche nach einer Möglichkeit, Zeilen einer Textdatei einzeln zentriert auf dem Bildschirm anzuzeigen

Ich suche nach einer Möglichkeit, eine Textdatei zu nehmen und jede Zeile einzeln und mit einer bestimmten Zeichenbreite zentriert auf dem Bildschirm anzuzeigen.

So ähnlich wie eine Diashow mit dem Grundgerüst, bei der der Benutzer beispielsweise die erste Zeile sieht, bis er eine Taste drückt, und dann die nächste Zeile, bis alle Zeilen angezeigt wurden.

Ich vermute, dass es hierfür eine einfache Möglichkeit in Bash gibt, habe aber noch keine Antwort gefunden.

Antwort1

So ähnlich:

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

Geben Sie ihm einen Namen centered.shund verwenden Sie es folgendermaßen:

./centered.sh centered.sh

Es wird jede Zeile aus der angegebenen Datei gedruckt. Drücken Sie eine beliebige Taste, um die nächste Zeile anzuzeigen. Beachten Sie, dass es noch nicht gut getestet ist, also verwenden Sie es mit Vorsicht. Außerdem werden Zeilen immer beginnend in der Bildschirmmitte gedruckt, sodass lange Zeilen weiter unten erscheinen.

Die erste Zeile:

#!/usr/bin/env bash

ist einsiebang. Außerdem verwende ich envfürseine Eigenschaften. Ich habe versucht, Bash zu vermeiden und dieses Skript in der POSIX-Shell zu schreiben, habe es aber aufgegeben, weil es besonders readproblematisch war. Sie sollten bedenken, dass Bash zwar allgegenwärtig zu sein scheint, aber nicht überall standardmäßig voreingestellt ist, beispielsweise auf BSD oder kleinen eingebetteten Systemen mit Busybox.

In diesem Teil:

if [ ! "$#" -eq 1 ]
then
    printf "Usage: %s <file>\n" "$0" >&2
    exit 1
fi

Wir prüfen, ob der Benutzer genau einen Parameter angegeben hat. Wenn nicht, drucken wir die Nutzungsinformationen in die Standardfehlerausgabe und geben 1 zurück. Dies bedeutet, dass ein Fehler bei einem übergeordneten Prozess aufgetreten ist.

Hier

file="$1"

Wir weisen den vom Benutzer übergebenen Dateinamenparameter einer Variablen zu, filedie wir später verwenden werden.

Dies ist eine Funktion, die tatsächlich zentrierten Text druckt:

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"
}

Es gibt keine Funktionsprototypen in Bash, daher können Sie nicht im Voraus wissen, wie viele Parameter die Funktion benötigt - diese benötigt nur einen Parameter, nämlich eine zu druckende Zeile, und diese wird dereferenziert mit $1Diese Funktion löscht zuerst den Bildschirm, bewegt sich dann vom oberen Bildschirmrand um Zeilen/2 nach unten, um die Bildschirmmitte zu erreichen, und druckt dann eine zentrierte Zeile mit der Methode, die ich von übernommen habeHier.

Dies ist die Schleife, die die vom Benutzer übergebene Eingabedatei liest und display_center()die Funktion aufruft:

while IFS= read -r line
do
    display_center "$line"
    read -n 1 -s -r </dev/tty
done < "$file"

readwird verwendet, um -n 1nur ein Zeichen zu lesen, -sdie Eingabe von einem Terminal nicht zu wiederholen und -rumVerhindern Sie die Verstümmelung von Backslashes. Weitere Informationen finden Sie readunter help read. Wir lesen auch direkt von /dev/tty, da stdin bereits auf die Datei verweist. Wenn wir nicht anweisen würden, readvon /dev/tty zu lesen, würde das Skript sehr schnell alle Zeilen aus der Datei drucken und sofort beendet werden, ohne darauf zu warten, dass der Benutzer eine Taste drückt.

Antwort2

Sie können es mit dem Paket tun 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

Es handelt sich um eine textbasierte Präsentation (ich habe „einfache Diashow“ ernst genommen!), die keine X-Sitzung erfordert und bei der immer nur eine Zeile angezeigt wird. Sie können vor- oder zurückblättern und die Präsentation endet nach der letzten Zeile.

Antwort3

Hier ist ein kurzer, schmutziger Einzeiler:

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

Dies setzt ein 80x24-Terminalfenster voraus. Der sedBefehl zentriert jede Textzeile und fügt dann genügend führende und nachfolgende Zeilenumbrüche hinzu, um sie vertikal zu zentrieren. Der moreBefehl ermöglicht dem Benutzer das Durchblättern.

verwandte Informationen