BASH 中的单词数组边框
Border an array of words in BASH
我一直在学习Bash,我的老师做了一个让我感到困惑的练习。
我只是在努力添加单词前面的空格。
代码应考虑到每个单词中的字符数,并调整星号和间距的数量,使其始终对齐。
它应该是这样的:
***********
* Hello *
* World *
* good *
* etceter *
***********
我的代码:
#determine biggest word
words=("Hello" "World" "good" "etceter")
numchar=0
for i in ${words[@]}; do
if [ ${#i} -gt $numchar ]
then
numchar=${#i}
fi
done
#write *
a=-4
while [ $a -lt $numchar ]; do
printf "*"
((a++))
done
#write array
echo
for txt in ${words[@]}; do
space=$(($numchar-${#txt}))
s=0
echo "* $txt "
while [ $s -lt $space ]; do
printf " "
((s++))
printf "*"
done
done
#write *
a=-4
while [ $a -lt $numchar ]; do
printf "*"
((a++))
done
我正在努力处理#write 数组部分。
非常感谢!
您只需要进行一些更改。
#write array
echo
for txt in ${words[@]}; do
space=$(($numchar-${#txt}))
s=0
echo -n "* $txt " # -n added to not append a newline
while [ $s -lt $space ]; do
echo -n " " # switched from printf to echo (cosmetics)
((s++))
# printf "*" # commented out
done
echo "*" # added
done
您的 while
循环仅在当前单词后添加空格。尾随的 *
出现在结束这一行的循环之后。
重写最后 3 个部分:
# define solid string of asterisks
printf -v stars '*%.0s' $(seq 1 $(( numchar + 4)) ) # length = numchar + 4
echo "${stars}"
for txt in "${words[@]}"
do
printf "* %-*s *\n" "${numchar}" "${txt}"
done
echo "${stars}"
这会生成:
***********
* Hello *
* World *
* good *
* etceter *
***********
你是在正确的轨道上首先得到最长的线的长度。
边框和填充可以完全用 printf
格式说明符和模式替换来完成。使用 %-Ns
左对齐,%Ns
右对齐。
如果引用正确,您也可以在每行中包含多个单词和空格。
这是一个例子:
lines=('Hello World!'
'Line two.'
a-line
'another line'
'The end.')
# border character
c='*'
# get length of longest line, required for padding
for i in "${lines[@]}"; do
((${#i} > pad)) &&
pad=${#i}
done
# make a string to fill top/bottom
fill=$(printf %$((pad + 4))s "$c")
fill=${fill// /$c}
# print the text box
printf '%s\n' "$fill"
for line in "${lines[@]}"; do
printf "$c %-${pad}s $c\n" "$line"
done
printf '%s\n' "$fill"
输出:
****************
* Hello World! *
* Line two. *
* a-line *
* another line *
* The end. *
****************
它有点硬编码,但认为您明白了:
$ echo '***********'; printf '* %-8s*\n' "${words[@]}"; echo '***********'
***********
* Hello *
* World *
* good *
* etceter *
***********
我一直在学习Bash,我的老师做了一个让我感到困惑的练习。
我只是在努力添加单词前面的空格。
代码应考虑到每个单词中的字符数,并调整星号和间距的数量,使其始终对齐。
它应该是这样的:
***********
* Hello *
* World *
* good *
* etceter *
***********
我的代码:
#determine biggest word
words=("Hello" "World" "good" "etceter")
numchar=0
for i in ${words[@]}; do
if [ ${#i} -gt $numchar ]
then
numchar=${#i}
fi
done
#write *
a=-4
while [ $a -lt $numchar ]; do
printf "*"
((a++))
done
#write array
echo
for txt in ${words[@]}; do
space=$(($numchar-${#txt}))
s=0
echo "* $txt "
while [ $s -lt $space ]; do
printf " "
((s++))
printf "*"
done
done
#write *
a=-4
while [ $a -lt $numchar ]; do
printf "*"
((a++))
done
我正在努力处理#write 数组部分。
非常感谢!
您只需要进行一些更改。
#write array
echo
for txt in ${words[@]}; do
space=$(($numchar-${#txt}))
s=0
echo -n "* $txt " # -n added to not append a newline
while [ $s -lt $space ]; do
echo -n " " # switched from printf to echo (cosmetics)
((s++))
# printf "*" # commented out
done
echo "*" # added
done
您的 while
循环仅在当前单词后添加空格。尾随的 *
出现在结束这一行的循环之后。
重写最后 3 个部分:
# define solid string of asterisks
printf -v stars '*%.0s' $(seq 1 $(( numchar + 4)) ) # length = numchar + 4
echo "${stars}"
for txt in "${words[@]}"
do
printf "* %-*s *\n" "${numchar}" "${txt}"
done
echo "${stars}"
这会生成:
***********
* Hello *
* World *
* good *
* etceter *
***********
你是在正确的轨道上首先得到最长的线的长度。
边框和填充可以完全用 printf
格式说明符和模式替换来完成。使用 %-Ns
左对齐,%Ns
右对齐。
如果引用正确,您也可以在每行中包含多个单词和空格。
这是一个例子:
lines=('Hello World!'
'Line two.'
a-line
'another line'
'The end.')
# border character
c='*'
# get length of longest line, required for padding
for i in "${lines[@]}"; do
((${#i} > pad)) &&
pad=${#i}
done
# make a string to fill top/bottom
fill=$(printf %$((pad + 4))s "$c")
fill=${fill// /$c}
# print the text box
printf '%s\n' "$fill"
for line in "${lines[@]}"; do
printf "$c %-${pad}s $c\n" "$line"
done
printf '%s\n' "$fill"
输出:
****************
* Hello World! *
* Line two. *
* a-line *
* another line *
* The end. *
****************
它有点硬编码,但认为您明白了:
$ echo '***********'; printf '* %-8s*\n' "${words[@]}"; echo '***********'
***********
* Hello *
* World *
* good *
* etceter *
***********