我正在尋找一種方法來獲取文本文件並將每一行一次一個地以一定的字元寬度放在螢幕中央。
有點像是簡單的幻燈片放映,例如,在使用者按下某個鍵之前查看第一行,然後查看下一行,直到查看完所有行。
我懷疑 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 shell 中編寫此腳本,但我放棄了,因為特別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
指令允許使用者翻頁。