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.sh
e 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 env
parasuas características. Tentei evitar o Bash e escrever esse script no shell POSIX, mas desisti porque read
era 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
file
que 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 $1
Esta 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 1
ler apenas um caractere, -s
para não ecoar a entrada vinda de um terminal e -r
paraevitar barras invertidas. Você pode aprender mais sobre read
em help read
. Também lemos de /dev/tty diretamente porque stdin já aponta para o arquivo - se não disséssemos read
para 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 dialog
o 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 sed
comando centraliza cada linha de texto e, em seguida, adiciona novas linhas iniciais e finais suficientes para centralizar verticalmente. O more
comando permite que o usuário navegue.