Rah*_*til 9 shell-script tput printf
我创建了这个函数,它打印输出,如示例图像中所示。但是,这个功能的实现似乎太复杂了。
有什么方法可以改进它或实施替代解决方案吗?

#!/bin/bash
function box_out() {
input_char=$(echo "$@" | wc -c)
line=$(for i in `seq 0 $input_char`; do printf "-"; done)
# tput This should be the best option. what tput does is it will
# read the terminal info and render the correctly escaped ANSI code
# for you.
# Code like \033[31m will break the readline library in some of the
# terminals.
tput bold
line="$(tput setaf 3)${line}"
space=${line//-/ }
echo " ${line}"
printf '|' ; echo -n "$space" ; printf "%s\n" '|';
printf '| ' ;tput setaf 4; echo -n "$@"; tput setaf 3 ; printf "%s\n" ' |';
printf '|' ; echo -n "$space" ; printf "%s\n" '|';
echo " ${line}"
tput sgr 0
}
box_out $@
Run Code Online (Sandbox Code Playgroud)
man*_*ork 16
由于您的 shebang 和语法表明 unportable bash,我更喜欢这样:
function box_out()
{
local s="$*"
tput setaf 3
echo " -${s//?/-}-
| ${s//?/ } |
| $(tput setaf 4)$s$(tput setaf 3) |
| ${s//?/ } |
-${s//?/-}-"
tput sgr 0
}
Run Code Online (Sandbox Code Playgroud)
当然,您可以根据需要对其进行优化。
根据评论中的要求进行更新,以处理多行文本。
function box_out()
{
local s=("$@") b w
for l in "${s[@]}"; do
((w<${#l})) && { b="$l"; w="${#l}"; }
done
tput setaf 3
echo " -${b//?/-}-
| ${b//?/ } |"
for l in "${s[@]}"; do
printf '| %s%*s%s |\n' "$(tput setaf 4)" "-$w" "$l" "$(tput setaf 3)"
done
echo "| ${b//?/ } |
-${b//?/-}-"
tput sgr 0
}
Run Code Online (Sandbox Code Playgroud)
使用多个参数调用它,例如box_out 'first line' 'more line' 'even more line'.
所以,我的解决方案与你的不太一样,但严格来说它在文本周围打印一个框,而且实现更简单,所以我想我会分享。
banner() {
msg="# $* #"
edge=$(echo "$msg" | sed 's/./#/g')
echo "$edge"
echo "$msg"
echo "$edge"
}
Run Code Online (Sandbox Code Playgroud)
这是在行动:
$ banner "hi"
######
# hi #
######
$ banner "hi there"
############
# hi there #
############
Run Code Online (Sandbox Code Playgroud)
只是纯文本,没有花哨的ansi颜色或任何东西。
$ echo 'Love Unix & Linux' | boxes -d stone -p a2v1
+---------------------+
| |
| Love Unix & Linux |
| |
+---------------------+
Run Code Online (Sandbox Code Playgroud)
由于boxes需要将文本作为文件发送给它,我建议使用上面示例中的语法,其中文本boxes通过echo.
boxes?”使用它很容易。只需告诉它您想使用哪种边框设计以及您希望它如何显示,您就完成了。
当然,如果你想有创意,你可以制作自己的设计。这真的很容易而且很有趣。使用的唯一缺点boxes是我还没有弄清楚如何将生成的框boxes居中以将中心与屏幕对齐,尽管有一个 bash hack
最初的问题已经证明了颜色代码的使用。因此,展示如何boxes处理这个问题似乎是正确的。
虽然tput很受欢迎,但我认为自己是一个老派的 Bash 人,仍然喜欢使用转义命令。我敢肯定 StackExchange 有一些人会反对它,但每个人都反对。无论如何,我愿意抛开我的个人偏好,包括另一个这样做的例子tput。
自然,我认为第一步是设置内部文本的颜色。所以让我们先这样做。
printf "$(tput setaf 4)Love Unix & Linux$(tput sgr 0)" | boxes -d stone -p a2v1
+---------------------------------+
| |
| Love Unix & Linux |
| |
+---------------------------------+
Run Code Online (Sandbox Code Playgroud)
如果这是在终端中,Love Unix & Linux将是蓝色的……但是正如您所看到的,boxes处理得不好。所以没出什么问题?
printf "$(tput setaf 4)Love Unix & Linux$(tput sgr 0)" | boxes -d stone -p a2v1 | cat -A
+---------------------------------+$
| |$
| ^[[34mLove Unix & Linux^[(B^[[0m |$
| |$
+---------------------------------+$
Run Code Online (Sandbox Code Playgroud)
通过显示隐藏字符进行仔细检查,cat -A显示boxes假定框的长度包括文本和转义字符的长度。
但应该注意的是,如果您使用诸如外部的程序,则输出如下所示lolcat boxes
$ echo 'Love Unix & Linux' | boxes -d stone -p a2v1 | lolcat -f
+---------------------+
| |
| Love Unix & Linux |
| |
+---------------------+
Run Code Online (Sandbox Code Playgroud)
但是框和文本为彩虹色。
这是一件好事,我还没有制作自己的边框设计,其中包含颜色代码,因为我认为边框设计会遇到同样的问题。
另一个缺陷弄清楚了。boxes是,如果您知道如何使用 Bash 将文本居中到终端的 with ,boxes则仍会将框与屏幕左侧对齐。
当您想要将不在框中的文本居中时,您可以简单地使用
center(){
COLS=$(tput cols) # use the current width of the terminal.
printf "%*s\n" "$(((${#1}+${COLS})/2))" "$1"
}
Run Code Online (Sandbox Code Playgroud)
并使用它来居中一行文本。
center 'Love Unix & Linux'
Run Code Online (Sandbox Code Playgroud)
对于使用多行且必须固定到位的 ascii-art,有此选项。
# Rather than removing text, even things out by padding lines with spaces
draw_banner(){
local banner="$1"
# Banner Width
BW=$(cat $banner | awk '{print length}' | sort -nr | head -1)
while IFS= read -r line; do
line=$(echo "${line}" | sed -n -e 's/^ / /g;p')
line=$(printf "%-${BW}s" "${line}")
center "${line}" # our center function from earlier.
done < "$banner"
}
draw_banner "path/to/your_ascii_art_logo.txt"
Run Code Online (Sandbox Code Playgroud)
但是,如果您喜欢使用诸如 之类的东西figlet,则不需要使用这些功能,因为该-c选项提供了居中选项。
$figfontdir="path/to/figlet/fonts"
$figfont="Alligator"
text_banner(){
COLS=$(tput cols) # use the width of the terminal!
figlet -d "$figfontdir" -f "$figfont" -k -w $COLS -c "$1"
}
text_banner 'Love Unix & Linux'
Run Code Online (Sandbox Code Playgroud)
对于boxes,我们做了类似的事情,draw_banner()但我们需要管道数据!
# Center a box created with `boxes
# It's like draw_banner, but `<<<` reads a string of data rather than a file.
$boxfile="/path/to/your_box_designs.box" # or ".txt". I like ".box".
$boxdesgin="stone"
center_box(){
local data="$(</dev/stdin)" # Read from standard input
# Banner Width
BW=$(cat <<< ${data} | awk '{print length}' | sort -nr | head -1)
while IFS= read -r line; do
line=$(echo "${line}" | sed -n -e 's/^ / /g;p')
line=$(printf "%-${BW}s" "${line}")
center "${line}" # our center command from earlier.
done <<< "${data}"
}
(
# A bunch of stuff to center!
) | boxes -f $boxfile -d $boxdesign -a hcvcjc | center_box
Run Code Online (Sandbox Code Playgroud)
解决这两个问题,UTF/ANSI 字符问题不仅可以boxes为将文本封装在 ASCII 框中提供更好的解决方案,而且可以提供一种可以调用的创造性替代方法,而不是手动编码框。
| 归档时间: |
|
| 查看次数: |
14710 次 |
| 最近记录: |