如何遍历Bash中由变量定义的一系列数字?

当范围由变量给出时,如何迭代Bash中的一系列数字?

我知道我可以做到这一点(在Bash文档中称为“序列表达式”):

 for i in {1..5}; do echo $i; done

这使:

1
2
3
4

然而,我怎样才能用变量替换范围端点? 这不起作用:

END=5
for i in {1..$END}; do echo $i; done

打印:

{} 1..5


for i in $(seq 1 $END); do echo $i; done

编辑:我更喜欢seq在其他方法,因为我实际上可以记住它;)


seq方法是最简单的,但Bash具有内置的算术评估。

END=5
for ((i=1;i<=END;i++)); do
    echo $i
done
# ==> outputs 1 2 3 4 5 on separate lines

for ((expr1;expr2;expr3)); 像C语言和类似语言中的for (expr1;expr2;expr3)一样构造工作,和其他((expr))情况一样,Bash将它们视为算术。


讨论

正如Jiaaro所说,使用seq很好。 Pax Diablo提出了一个Bash循环来避免调用一个子进程,如果$ END太大,还有更多的内存友好。 Zathrus在循环实现中发现了一个典型的错误,并且暗示说由于i是一个文本变量,所以连续转换来回数字时会执行相关的减速操作。

整数算术

这是Bash循环的改进版本:

typeset -i i END
let END=5 i=1
while ((i<=END)); do
    echo $i
    …
    let i++
done

如果我们想要的唯一的东西是echo ,那么我们可以编写echo $((i++))

ephemient教会了我一些东西:Bash允许for ((expr;expr;expr))构造。 由于我从来没有阅读Bash的整个手册页(就像我用Korn shell( ksh )手册页完成的那样),但我错过了这一点。

所以,

typeset -i i END # Let's be explicit
for ((i=1;i<=END;++i)); do echo $i; done

似乎是最具有内存效率的方式(不需要分配内存来消耗seq的输出,如果END非常大,这可能会成为问题),尽管可能不是“最快”的。

最初的问题

eschercycle指出{a..b} Bash符号只适用于文字; 真实的,因此Bash手册。 可以用一个没有exec()的单一(内部) fork()来克服这个障碍(就像调用seq ,这是另一个图像需要fork + exec一样):

for i in $(eval echo "{1..$END}"); do

evalecho都是Bash buildins,但是命令替换( $(…)构造)需要fork() )。

链接地址: http://www.djcxy.com/p/17459.html

上一篇: How do I iterate over a range of numbers defined by variables in Bash?

下一篇: How to test strings for less than or equal?