Buscando una manera de ver las líneas de un archivo de texto una a la vez centradas en la pantalla

Buscando una manera de ver las líneas de un archivo de texto una a la vez centradas en la pantalla

Estoy buscando una manera de tomar un archivo de texto y colocar cada línea una a la vez centrada en la pantalla con un cierto ancho de caracteres.

Algo así como una presentación de diapositivas básica, por ejemplo, ver la primera línea hasta que el usuario presiona una tecla y luego ver la siguiente línea, hasta que se hayan visto todas las líneas.

Sospecho que existe una forma básica de hacer esto en bash, pero aún no he encontrado una respuesta.

Respuesta1

Algo como eso:

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

Nómbralo centered.shy úsalo así:

./centered.sh centered.sh

Imprimirá cada línea del archivo proporcionado. Presione cualquier tecla para mostrar la siguiente línea. Tenga en cuenta que aún no está bien probado, así que úselo con precaución y que siempre imprimirá líneas comenzando desde el centro de la pantalla, por lo que las líneas largas aparecerán más en la parte inferior.

La primera línea:

#!/usr/bin/env bash

es unel asunto. Además, lo uso envparasus caracteristicas. Intenté evitar Bash y escribir este script en el shell POSIX, pero lo dejé porque readera especialmente muy problemático. Debes tener en cuenta que, aunque pueda parecer que Bash es omnipresente, no está predeterminado en todas partes, por ejemplo en BSD o en pequeños sistemas integrados con Busybox.

En esta parte:

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

Verificamos si el usuario proporcionó exactamente un parámetro y, si no lo hizo, imprimimos la información de uso como error estándar y devolvemos 1, eso significa un error en un proceso principal.

Aquí

file="$1"

Asignamos el parámetro de nombre de archivo que el usuario ha pasado a una variable fileque usaremos más adelante.

Esta es una función que en realidad imprime texto centrado:

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

No hay prototipos de funciones en Bash, por lo que no se puede saber cuántos parámetros toma la función de antemano; ese solo toma un parámetro, que es una línea para imprimir y se desreferencia usando $1Esta función primero limpia la pantalla, luego baja líneas/ 2 desde la parte superior de la pantalla para llegar al centro de la pantalla y luego imprime la línea centrada usando el método que tomé prestadoaquí.

Ese es el bucle que lee el archivo de entrada pasado por el usuario y llama a display_center()la función:

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

readse utiliza para -n 1leer solo un carácter, -spara no hacer eco de la entrada procedente de un terminal y -rparaevitar destrozar barras invertidas. Puedes conocer más sobre readen help read. También leemos desde /dev/tty directamente porque stdin ya apunta al archivo; si no le dijimos readque leyera desde /dev/tty, el script imprimiría muy rápidamente todas las líneas del archivo y saldría inmediatamente sin esperar a que el usuario lo haga. presione una tecla.

Respuesta2

Puedes hacerlo con dialogel paquete:

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 una presentación basada en texto (¡me tomé en serio la "presentación de diapositivas básica"!), no requiere sesión X, y muestra una línea a la vez. Puedes avanzar o retroceder y termina después de la última línea.

Respuesta3

Aquí hay una frase rápida y sucia:

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

Esto supone una ventana de terminal de 80x24. El sedcomando centra cada línea de texto y luego agrega suficientes líneas nuevas iniciales y finales para centrarlas verticalmente. El morecomando permite al usuario desplazarse por las páginas.

información relacionada