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 *
***********