关于shell:在bash for循环中评估表达式

Evaluate expression inside bash for loop

本问题已经有最佳答案,请猛点这里访问。

如果我这样做,我会得到预期的结果。

1
2
3
4
5
6
for i in {125..129}; do echo $i; done
125
126
127
128
129

但是当我这样做的时候? 我得到了一些东西。

1
2
3
for i in {$((1+(25-1)*500))..$((25*500))}; do echo $i; done

{12001..12500}

我希望在循环变量中传递一个变量,如$((1+($j-1)*500))


Bash的支撑扩展有局限性。你想要的是seq

1
for i in $( seq $((1+(25-1)*500)) $((25*500)) ); do echo $i; done

以上将循环遍历从12001到12500的所有数字。

讨论

seq类似于bash的大括号:

1
2
3
4
$ echo {2..4}
2 3 4
$ echo $(seq 2 4)
2 3 4

seq的主要优点是它的参数不仅包括算术表达式,如上所示,还包括shell变量:

1
2
$ x=4; echo $(seq $((x-2)) $x)
2 3 4

相比之下,括号符号也不会接受。

seq是一个GNU实用程序,可用于所有Linux系统以及最新版本的OSX。较旧的BSD系统可以使用名为jot的类似实用程序。


您的查询非常类似于:
shell脚本"for"循环语法

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

而是试试

我在seq $((1+(25-1)*500)) $((25*500));回声$ i; DONE


支撑扩展是在参数,变量和算术扩展之前发生的第一次扩展。如果..之前和之后的值是整数或单个字符,则仅使用..进行括号扩展。由于您的示例中的算术扩展尚未发生,因此它们不是单个字符或整数,因此不会发生大括号扩展。

使用eval进行算术扩展后,可以强制重新展开:

1
for i in $(eval echo {$((1+(25-1)*500))..$((25*500))}); do echo $i;

试试这个

1
for (( i= $((1+(25-1)*500)); i<=$((25*500)); i++ )); do echo $i; done

或这个

1
for i in $(seq $(( 1+(25-1)*500 )) $(( 25*500 )) ); do echo $i; done

请勿使用for循环执行此操作。 {..}表示法并不灵活:

1
i=$((1+(25-1)*500)); while test $i -le $((25*500)); do echo $((i++)); done


它只是回应正如它所说的文字:

{} 12001..12500

那是"{"+12001 +"......"+ 12500+"}"