如何创建循环序列?

Inv*_*ker 5 linux shell-script

我正在尝试创建一个脚本,该脚本将从用户那里获取一个变量,并应打印如下金字塔:

*
**
***
****
*****
Run Code Online (Sandbox Code Playgroud)

我使用了这个脚本,但它显示了数字:

for i in {1..5}

do

a=${a}${i}

echo ${a}

done
Run Code Online (Sandbox Code Playgroud)

输出:

1
12
123
1234
12345
Run Code Online (Sandbox Code Playgroud)

如何插入“*”符号而不是数字?

Dig*_*uma 8

只需将*字符附加到a变量,而不是循环计数器:

for i in {1..5}
do
  a+='*'
  echo "${a}"
done
Run Code Online (Sandbox Code Playgroud)

请注意,a="${a}*"而不是a+='*'同样有效,但我认为该+=版本更整洁/更清晰。

如果你想用一个 while 循环来做到这一点,你可以这样做:

while (( "${#a}" < 5 )); do
  a+='*'
  echo "$a"
done
Run Code Online (Sandbox Code Playgroud)

${#a}扩展到a变量中字符串的长度。

请注意,上述两个代码片段(以及问题中的代码)都假定avar 为空或未在代码片段的开头设置。如果不是这种情况,那么您需要先重新初始化它:

a=
Run Code Online (Sandbox Code Playgroud)

我假设您正在使用 bash shell。 这是完整的手册。 这是关于循环结构部分。


Ste*_*itt 5

在这种情况下,Digital Trauma的答案更有效,但为了完整起见,您可以使用传统的 shell 方法重复使用printf以下字符:

for i in {1..5}
do
  printf "%${i}s\n"
done | sed 's/ /*/g'
Run Code Online (Sandbox Code Playgroud)

这用于printf根据需要输出尽可能多的空格,然后sed用我们真正想要的字符替换空格。

正如Digital TraumaJanis所指出的,您可以将 的结果存储printf在变量中并使用外壳的子字符串替换来避免使用sed(以在许多情况下产生大量子外壳为代价):

for i in {1..5}
do
  a=$(printf "%${i}s")
  echo "${a// /*}"
done
Run Code Online (Sandbox Code Playgroud)

这里的引号是必要的,echo以避免 shell 解释*字符。此外,echo\n不再需要。

正如kojiro所指出的,tr比 更适合替换单个字符sed

for i in {1..5}
do
  printf "%${i}s\n"
done | tr ' ' '*'
Run Code Online (Sandbox Code Playgroud)

(但该sed变体允许重复任何长度的文本。)