Procurando uma maneira de visualizar as linhas de um arquivo de texto, uma de cada vez, centralizada na tela

Procurando uma maneira de visualizar as linhas de um arquivo de texto, uma de cada vez, centralizada na tela

Estou procurando uma maneira de pegar um arquivo de texto e colocar cada linha, uma de cada vez, centralizada na tela com uma determinada largura de caracteres.

Mais ou menos como uma apresentação de slides básica, por exemplo, vendo a primeira linha até que o usuário pressione uma tecla e depois vendo a próxima linha, até que todas as linhas tenham sido visualizadas.

Suspeito que exista uma maneira básica de fazer isso no bash, mas ainda não encontrei uma resposta.

Responder1

Algo parecido:

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

Dê um nome centered.she use assim:

./centered.sh centered.sh

Ele imprimirá cada linha do arquivo fornecido. Pressione qualquer tecla para mostrar a próxima linha. Observe que ainda não foi bem testado, então use com cuidado e sempre imprimirá linhas começando no centro da tela, fazendo com que linhas longas apareçam mais na parte inferior.

A primeira linha:

#!/usr/bin/env bash

é umShebang. Além disso, eu uso envparasuas características. Tentei evitar o Bash e escrever esse script no shell POSIX, mas desisti porque readera especialmente muito problemático. Você deve ter em mente que, embora pareça que o Bash é onipresente, ele não está predefinido em todos os lugares por padrão, por exemplo, no BSD ou em pequenos sistemas embarcados com Busybox.

Nesta parte:

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

verificamos se o usuário forneceu exatamente um parâmetro e, caso contrário, imprimimos as informações de uso no erro padrão e retornamos 1, o que significa um erro no processo pai.

Aqui

file="$1"

atribuímos o parâmetro filename que o usuário passou para uma variável fileque usaremos mais tarde.

Esta é uma função que realmente imprime texto centralizado:

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

Não há protótipos de função no Bash, então você não pode saber quantos parâmetros a função leva com antecedência - aquele leva apenas um parâmetro que é uma linha para imprimir e é desreferenciado usando $1Esta função primeiro limpa a tela e depois desce por linhas/ 2 da parte superior da tela para chegar ao centro da tela e então imprime a linha centralizada usando o método que peguei emprestadoaqui.

Esse é o loop que lê o arquivo de entrada passado pelo usuário e chama display_center()a função:

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

readé usado para -n 1ler apenas um caractere, -spara não ecoar a entrada vinda de um terminal e -rparaevitar barras invertidas. Você pode aprender mais sobre readem help read. Também lemos de /dev/tty diretamente porque stdin já aponta para o arquivo - se não disséssemos readpara ler de /dev/tty o script imprimiria rapidamente todas as linhas do arquivo e sairia imediatamente sem esperar que o usuário pressione uma tecla.

Responder2

Você pode fazer isso com dialogo pacote:

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

É uma apresentação baseada em texto (levei a sério a "apresentação de slides básica"!), sem necessidade de sessão X, que exibe uma linha por vez. Você pode retroceder ou avançar e termina após a última linha.

Responder3

Aqui está uma frase rápida e suja:

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

Isso pressupõe uma janela de terminal 80x24. O sedcomando centraliza cada linha de texto e, em seguida, adiciona novas linhas iniciais e finais suficientes para centralizar verticalmente. O morecomando permite que o usuário navegue.

informação relacionada