Shell脚本“for”循环语法

时间:2009-09-18 15:57:39

标签: unix syntax shell

我已经完成了以下工作:

for i in {2..10}
do
    echo "output: $i"
done

它产生了许多行output: 2output: 3,等等。

但是,尝试运行以下内容:

max=10
for i in {2..$max}
do
    echo "$i"
done

产生以下内容:

output: {2..10}

如何让编译器实现它应该将$ max视为数组的另一端,而不是字符串的一部分?

11 个答案:

答案 0 :(得分:209)

支撑扩展, {x..y} 在其他扩展之前执行,因此您不能将其用于可变长度序列。

相反,请将seq 2 $max方法用作user mob stated

因此,对于您的示例,它将是:

max=10
for i in `seq 2 $max`
do
    echo "$i"
done

答案 1 :(得分:66)

尝试for的算术表达式版本:

max=10
for (( i=2; i <= $max; ++i ))
do
    echo "$i"
done

这在大多数版本的bash中都可用,并且也应该与Bourne shell(sh)兼容。

答案 2 :(得分:27)

手动循环:

i=0
max=10
while [ $i -lt $max ]
do
    echo "output: $i"
    true $(( i++ ))
done

如果您不必完全是POSIX,则可以使用算术进行循环:

max=10
for (( i=0; i < max; i++ )); do echo "output: $i"; done

或者在BSD系统上使用 jot (1):

for i in $( jot 0 10 ); do echo "output: $i"; done

答案 3 :(得分:9)

有多种方法可以做到。

max=10
for i in `eval "echo {2..$max}"`
do
    echo "$i"
done

答案 4 :(得分:8)

如果系统上有seq命令:

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

注意那些引号。

答案 5 :(得分:4)

这是一种方式:
击:

max=10
for i in $(bash -c "echo {2..${max}}"); do echo $i; done

ksh分别替换为zshbash -c时,上述Bash方式也适用于ksh -czsh -c

注意:for i in {2..${max}}; do echo $i; done适用于zshksh

答案 6 :(得分:3)

我们可以像C编程一样迭代循环。

#!/bin/bash
for ((i=1; i<=20; i=i+1))
do 
      echo $i
done

答案 7 :(得分:2)

好吧,由于我的系统上没有安装seq命令(Mac OS X v10.6.1(Snow Leopard)),我最终使用了while循环:

max=5
i=1

while [ $max -gt $i ]
do
    (stuff)
done

* Shrugs *无论什么都有效。

答案 8 :(得分:2)

这适用于Mac OS X.

它包括BSD日期的示例,如何增加和减少日期:

for ((i=28; i>=6 ; i--));
do
    dat=`date -v-${i}d -j "+%Y%m%d"` 
    echo $dat
done

答案 9 :(得分:1)

使用:

max=10
for i in `eval echo {2..$max}`
do
    echo $i
done

您需要显式的'eval'调用来在变量替换后重新评估{}。

答案 10 :(得分:1)

这些都是{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