我正在尝试创建一个脚本,该脚本将从用户那里获取一个变量,并应打印一个金字塔,如下所示:
*
**
***
****
*****
我使用了这个脚本,但它显示了数字:
for i in {1..5}
do
a=${a}${i}
echo ${a}
done
输出:
1
12
123
1234
12345
如何插入“*”号而不是数字?
答案1
只需将*
字符附加到a
变量,而不是循环计数器:
for i in {1..5}
do
a+='*'
echo "${a}"
done
请注意,a="${a}*"
代替a+='*'
也同样有效,但我认为该+=
版本更整洁/更清晰。
如果您想用 while 循环来执行此操作,您可以执行以下操作:
while (( "${#a}" < 5 )); do
a+='*'
echo "$a"
done
${#a}
扩展到变量中字符串的长度a
。
请注意,上述两个代码片段(以及问题中的代码)都假设 vara
为空或在代码片段的开头未设置。如果不是这种情况,那么您需要先重新初始化它:
a=
我假设您正在使用 bash shell。 这是完整的手册。 这里是关于循环结构的部分。
答案2
数码创伤在这种情况下,答案更有效,但为了完整性,您可以使用传统的 shell 方法来重复字符printf
:
for i in {1..5}
do
printf "%${i}s\n"
done | sed 's/ /*/g'
这用于printf
输出所需数量的空格,然后sed
用我们真正想要的字符替换空格。
正如所指出的数码创伤和贾尼斯,您可以将结果存储printf
在变量中并使用 shell 的子字符串替换来避免使用sed
(在许多情况下以生成大量子 shell 为代价):
for i in {1..5}
do
a=$(printf "%${i}s")
echo "${a// /*}"
done
这里需要引号echo
以避免 shell 解释*
字符。此外,不再需要使用了echo
。\n
正如所指出的小次郎,tr
比 更适合替换单个字符sed
:
for i in {1..5}
do
printf "%${i}s\n"
done | tr ' ' '*'
(但该sed
变体允许重复任意长度的文本。)
答案3
POSIXly:
$ n=5 awk 'BEGIN{OFS="*";for(i=2;i<=ENVIRON["n"]+1;i++){$i="";print}}'
答案4
您可以使用sed
和 它的s/regexp/replacement/flags
命令。
seq 10 |sed 's/.*/printf "*%.0s" {1..&}/e'
*
**
***
****
*****
******
*******
********
*********
**********