#!/bin/sh
for i in {1..5}
do
echo "Welcome"
done
会工作,显示欢迎 5 次。
#!/bin/sh
howmany=`grep -c $1 /root/file`
for i in {1..$howmany}
do
echo "Welcome"
done
不工作!howmany将等于 5,因为这就是 的输出grep -c将显示的内容。$1 是参数 1,它在运行脚本时是特定的。
有任何想法吗?
#!/bin/sh
for i in {1..5}
do
echo "Welcome"
done
会工作,显示欢迎 5 次。
#!/bin/sh
howmany=`grep -c $1 /root/file`
for i in {1..$howmany}
do
echo "Welcome"
done
不工作!howmany将等于 5,因为这就是 的输出grep -c将显示的内容。$1 是参数 1,它在运行脚本时是特定的。
有任何想法吗?
如果意图只是在一个范围内迭代数字- 如在 OP 的情况下 -最好的选择不是使用大括号扩展,而是使用 bash 的C 样式循环- 请参阅user000001 的答案。
如果仍然需要使用大括号扩展:
如果您不需要列表中的数字具有前缀或后缀,请使用带有不带引号的命令替换的seq实用程序(小警告:不是 POSIX 实用程序,但它可以广泛使用);例如seq
echo $(seq 3)-> 1 2 3; 隐含的起始编号1
echo $(seq -f '%02.f' 3)-> 01 02 03- 零填充echo $(seq 2 4)-> 2 3 4; 明确的开始和结束数字echo $(seq 1 2 5)-> 1 3 5; 自定义增量(中间2的)如果您确实需要列表中的数字具有前缀或后缀,您有多种选择:
seq实用程序及其-f选项来提供printf-style 格式字符串(如上面用于零填充),或基于纯 Bash 变通办法eval(需要额外注意!)或在循环中构建数组,所有这些都在此详述回答。awk或)编写自定义脚本perl。eval安全使用驱动序列大括号表达式的变量的示例:变量事先经过验证,以确保它们包含十进制整数。
from=1 to=3 # sample values
# Ensure that $from and $to are decimal numbers and abort, if they are not.
(( 10#$from + 10#$to || 1 )) 2>/dev/null || { echo "Need decimal integers" >&2; exit 1; }
eval echo "A{$from..$to}" # -> 'A1 A2 A3'
大括号扩展的主要目的是扩展一个标记列表,每个标记都有一个可选的前缀和/或后缀;大括号扩展必须不加引号,并且有2 种风格:
echo A{b,c,d}-> Ab Ac Ad,即 3 个标记,由 args 的数量暗示。echo {/,$HOME/}Library例如,->/Library /User/jdoe/Library序列表达式(范围)..,通常为数字-不支持变量
{a..c}{1..10}, {10..1},{-1..2}
A{1..3}#->A1# A2# A3#{$from..$to} # !! FAILS-$from并被$to解释为文字,因此不能识别为单个字母或十进制整数 -不执行大括号扩展(见下文)。
zsh和ksh。echo A{1..5..2}-> A1 A3 A5- 数字加 2echo A{001..003}->A001 A002 A003无效的大括号表达式不会被扩展(像普通的不带引号的字符串一样对待,使用{和}对待作为文字):
echo {}-> '{}'- 作为大括号表达式无效:至少需要2 个 ,分隔标记
{}with find。echo {1..$to}-> '{1..<value-of-$to>}'- 作为大括号表达式无效。in bash:不支持变量;但是,在和中有效。kshzshfish相比之下,扩展任何 {...}序列;类似地,具有用于扩展内部单个字符的zsh选项BRACE_CCL(默认为关闭),这有效地导致任何非空序列的扩展。){..} {...}在扩展变量之前评估大括号扩展。你需要一个 c 风格的 for 循环来代替:
for ((i=1;i<=howmany;i++))
do
echo "Welcome"
done
创建一个序列来控制你的循环
for i in $(seq 1 $howmany); do
echo "Welcome";
done
问题是在“变量扩展”之前执行“大括号扩展”
for i in $(seq 1 $howmany)
正如@damienfrancois 所说的那样工作,或者,如果您愿意:
for i in $(eval echo "{$start..10}")
可能会,但不要为了每个人的理智而使用它。
您还可以使用 while 循环:
while ((howmany--)); do
echo "Welcome"
done
我们也可以eval在这种情况下使用:
howmany=`grep -c $1 /root/file`
for i in $(eval echo {1..$howmany}); do
echo "Welcome"
done