#!/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
:不支持变量;但是,在和中有效。ksh
zsh
fish
相比之下,扩展任何 {...}
序列;类似地,具有用于扩展内部单个字符的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