我已经使以下代码可以运行:
for i in {2..10}
do
echo "output: $i"
done
它产生一堆output: 2
,output: 3
等等的行。
然而,尝试运行以下代码:
max=10
for i in {2..$max}
do
echo "$i"
done
生成以下内容:
output: {2..10}
如何让编译器意识到$max是数组的另一端,而不是字符串的一部分呢?
花括号扩展,{x..y} 在其他扩展之前执行,因此您无法将其用于长度可变的序列。
相反,使用 seq 2 $max
方法,如用户mob所述。
因此,对于您的示例,它应该是:
max=10
for i in `seq 2 $max`
do
echo "$i"
done
seq
来计数和增加 for 循环中的数字,因此建议避免使用 seq
。该命令仅用于与旧版 bash 的兼容性。内置命令已经足够快了。
for (( EXP1; EXP2; EXP3 )) ...
- millerfor (( ... ))
语法不是 POSIX 标准,这意味着例如在 Alpine Linux 上它不会直接起作用,而 seq
可以。 - Wernight#!/bin/sh
是Dash。 - Franklin Yu试试使用算术表达式版本的 for
循环:
max=10
for (( i=2; i <= $max; ++i ))
do
echo "$i"
done
这在大多数版本的Bash中都可用,也应该与Bourne shell (sh)兼容。
sh
,而是将其作为指向其他Shell的链接。理想情况下,这样一个名为 sh
的Shell 将仅支持 POSIX 标准中的功能,但默认情况下也允许一些额外功能通过。C风格的for循环不是POSIX功能,但实际上的Shell可能在 sh
模式下支持。 - chepner手动执行循环:
i=0 max=10 while [ $i -lt $max ] do echo "输出:$i" true $(( i++ )) done
如果您不必完全遵循POSIX标准,可以使用算术 for 循环:
max=10 for (( i=0; i < max; i++ )); do echo "输出:$i"; done
或者在BSD系统上使用jot(1):
for i in $( jot 0 10 ); do echo "输出:$i"; done
true $(( i++ ))
并不适用于所有情况,因此最可移植的方法是 true $((i=i+1))
。 - Flowseq
命令可用:for i in `seq 2 $max`
do
echo "output: $i"
done
如果不行的话,那么可以使用“穷人版”的 seq
命令和 perl
来实现:
seq=`perl -e "\$,=' ';print 2..$max"`
for i in $seq
do
echo "output: $i"
done
注意引号的使用。
#!/bin/bash
for ((i=1; i<=20; i=i+1))
do
echo $i
done
有多种方法可以做到这一点。
max=10
for i in `eval "echo {2..$max}"`
do
echo "$i"
done
eval
将评估您设置的max
的任何内容,因此存在安全风险。请考虑max =“2}; echo ha;#”
,然后将echo ha
替换为更具破坏性的内容。 - chepnermax=10
for i in $(bash -c "echo {2..${max}}"); do echo $i; done
当用ksh -c
或zsh -c
替换bash -c
时,上述Bash方法也适用于ksh
和zsh
。
注意:for i in {2..${max}}; do echo $i; done
在zsh
和ksh
中有效。
因为我的系统(Mac OS X v10.6.1 (Snow Leopard))没有安装seq命令,所以我只好使用while循环代替:
max=5
i=1
while [ $max -gt $i ]
do
(stuff)
done
*耸肩* 那就用这个方法吧。
这些都是{1..8}
,并且都应该符合POSIX标准。如果在循环中放置条件continue
,它们也不会出错。惯用的写法:
f=
while [ $((f+=1)) -le 8 ]
do
echo $f
done
g=
while
g=${g}1
[ ${#g} -le 8 ]
do
echo ${#g}
done
还有一个:
set --
while
set $* .
[ ${#} -le 8 ]
do
echo ${#}
done
这在 Mac OS X 上是可行的。
它包括了一个 BSD 日期的示例,以及如何增加和减少日期:
for ((i=28; i>=6 ; i--));
do
dat=`date -v-${i}d -j "+%Y%m%d"`
echo $dat
done
for
和if
关键字与do
和then
关键字在同一行。例如:for i in {2..10}; do
- a paid nerdseq
不是POSIX标准化的。即使它存在,也不能保证具有任何特定的行为。这就是为什么在http://wooledge.org/~greybot/meta/counting(freenode #bash频道事实数据库中相关条目)讨论的模式中没有一个依赖于它的原因。 - Charles Duffy