Я ищу способ взять текстовый файл и поместить каждую строку по одной на экране по центру с определенной шириной символов.
Что-то вроде простого слайд-шоу, например, сначала отображается первая строка, пока пользователь не нажмет клавишу, а затем отображается следующая строка, пока не будут просмотрены все строки.
Подозреваю, что в bash есть простой способ сделать это, но ответа я пока не нашел.
решение1
Что-то вроде того:
#!/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
этопритон. Кроме того, я использую env
дляего особенности. Я пытался избегать Bash и написать этот скрипт в оболочке POSIX, но я сдался, потому что это read
было очень проблематично. Вы должны иметь в виду, что хотя может показаться, что Bash вездесущ, он не везде предустановлен по умолчанию, например, в BSD или небольших встраиваемых системах с Busybox.
В этой части:
if [ ! "$#" -eq 1 ]
then
printf "Usage: %s <file>\n" "$0" >&2
exit 1
fi
мы проверяем, предоставил ли пользователь ровно один параметр, и если нет, то выводим информацию об использовании в стандартный поток ошибок и возвращаем 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
Эта функция сначала очищает экран, затем перемещается вниз на строку/2 от верхней части экрана, чтобы достичь центра экрана, а затем печатает центрированную строку, используя метод, который я позаимствовал изздесь.
Это цикл, который считывает входной файл, переданный пользователем, и вызывает
display_center()
функцию:
while IFS= read -r line
do
display_center "$line"
read -n 1 -s -r </dev/tty
done < "$file"
read
используется -n 1
для чтения только одного символа, -s
чтобы не отображать ввод, поступающий с терминала, и -r
дляпредотвратить искажение обратных косых черт. Вы можете узнать больше о read
. help read
Мы также считываем данные из /dev/tty напрямую, поскольку stdin уже указывает на файл — если бы мы не указали read
на чтение из /dev/tty, скрипт очень быстро вывел бы все строки из файла и немедленно завершил бы работу, не дожидаясь нажатия клавиши пользователем.
решение2
Вы можете сделать это с помощью 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, которая отображает одну строку за раз. Вы можете перемещаться назад или вперед, и она заканчивается после последней строки.
решение3
Вот краткий и односложный ответ:
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
позволяет пользователю перелистывать страницы.