Shell 画圣诞树

Shell 画圣诞树,shell,for-loop,drawing,Shell,For Loop,Drawing,我正试着用下面的形式画一棵树 * *** ***** ******* ********* 正如你所看到的,我需要两个空格,每行都有“*”星,但我不能完全按照我想要的方式得到它 #!/bin/bash display_tree() { local rows=$1 local columns=$2 for ((i=0; i<$rows; i++)) do #spaces loop for ((j=

我正试着用下面的形式画一棵树

    *    
   ***
  *****
 *******
*********
正如你所看到的,我需要两个空格,每行都有“*”星,但我不能完全按照我想要的方式得到它

#!/bin/bash

display_tree() {
    local rows=$1
    local columns=$2

    for ((i=0; i<$rows; i++))
    do
        #spaces loop
        for ((j=0; j<$columns; j++))
        do
            echo -n " "
            #drawing tree loop
            for ((a=0; a<$(($i + 1)); a++))
            do
                echo -n "*"
            done
        done
    echo 
    done
}

if [ $# -eq 2 ]; then
    display_tree $1 $2
else
    echo "Usage: $0 rows columns"
fi
#/bin/bash
显示树(){
本地行=$1
本地列=$2

对于((i=0;i这似乎对我有效。建议使用奇数作为“columns”参数。当columns=2*行-1时,看起来最漂亮。代码中最长的一行执行一些初等代数,特别是线性插值,用于计算给定行中显示的星星数

#!/bin/bash
# Christmas tree ASCII drawer
# works nicest for odd integers

spaces() {
  for ((i=0; i<$1; i++)) ; do
    echo -n " "
  done 
}

stars() {
  for ((i=0; i<$1; i++)) ; do
    echo -n "*"
  done
  echo ""
}

display_tree() {
    local rows=$1
    local columns=$2

    # render
    for (( r=1; r <= $rows; r++ )); do
      s=$(( (((columns-1) * (r-1)/(rows-1) + 1)/2)*2 +1 ))
      spaces $(((columns-s)/2))
      stars $s
    done
}

if [ $# -eq 2 ]; then
    display_tree $1 $2
else
    echo "Usage: $0 rows columns"
fi

此解决方案的逻辑非常简单,最好的解释方法可能是在文本编辑器中绘制几层树,并计算每次迭代的星数和空格数。您很快就会意识到这涉及到生成一组数字。例如:

3 1
2 3 
1 5
0 7

您现在所要做的就是设置一个起点($COLUMNS/2)。 $(eval…)部分只是一个不使用 需要一个loop.Eval,因为没有它,支撑壳扩展{1..$var}无法工作

spaces=$(($COLUMNS/2)); 
for ((i=1; i < $LINES; i+=2)); 
    do echo "$(eval printf '\ %.0s' {1..$spaces}) $(eval printf '*%.0s' {1..$i})"; 
    ((spaces--));
done;
spaces=$($COLUMNS/2));
对于((i=1;i<$line;i+=2));
执行echo“$(eval printf'\%.0s'{1..$spaces})$(eval printf'*%.0s'{1..$i})”;
((空格-);
完成;

看起来您还没有正式确定在发射星星之前需要发射多少个空格,并且您已经包装了内部循环,而不是使它们连续。当树有3行高时,您需要在第1行、第2行和第3行的第一颗星星之前放置多少空格?您的代码如何确保这一点?(提示,它还没有-因此您必须修改它,直到它修改为止。)如果您修改最里面的循环以发出
printf“a=%s\ti=%s\tj=%s\n“$a$i$j>”/dev/tty???,您将更好地理解脚本的内部结构
其中???是在一个单独的窗口中运行
tty
,然后在我的示例中将数字替换为“?”。或者您可以省略
>“/dev/tty…”
并将输出与您的圣诞树混合。祝您好运。@Filnor我认为逻辑是显而易见的,但我想我错了。我将解释代码是如何工作的。
letters=( \" \');while true;do clear; letter=${letters[$[RANDOM%${#letters[@]}]]}; [[ $letter == \" ]] && color=35 || color=32;m=2;i=77;p=$(($i/2-1)); while [[ $m -le $i ]];do printf "%${p}s" ;printf "\e[4;${color}m${letter}%.0s\e[m" $(seq $m);echo;m=$[m+2];((p--));done;sleep 1;done 
spaces=$(($COLUMNS/2)); 
for ((i=1; i < $LINES; i+=2)); 
    do echo "$(eval printf '\ %.0s' {1..$spaces}) $(eval printf '*%.0s' {1..$i})"; 
    ((spaces--));
done;