在大括号扩展范围中使用变量馈送到 for 循环

Posted

技术标签:

【中文标题】在大括号扩展范围中使用变量馈送到 for 循环【英文标题】:Using a variable in brace expansion range fed to a for loop 【发布时间】:2012-04-12 06:06:33 【问题描述】:

这里是 myscript.sh

#!/bin/bash
for i in 1..$1;
do
    echo $1 $i;
done

如果我运行myscript.sh 3,输出是

3 1..3

而不是

3 1
3 2
3 3

显然$3 包含正确的值,那么为什么for i in 1..$1 的行为不像我直接写for i in 1..3 一样?

【问题讨论】:

您的示例脚本可以在 ksh93 和 zsh 中运行。 【参考方案1】:

您应该使用 C 风格的 for 循环来完成此操作:

for ((i=1; i<=$1; i++)); do
   echo $i
done

这避免了外部命令和讨厌的 eval 语句。

【讨论】:

不适合我test.sh: line 1: ((: i&lt;=: syntax error: operand expected (error token is "&lt;=") @Temak 你在用bash吗?你的shebang是#!/bin/bash还是#!/bin/sh @jordann,文件只包含这 3 行。我正在使用 GNU bash,版本 4.3.11(1)-release (x86_64-pc-linux-gnu)。我运行脚本bash test.sh @Temak 你需要像这样运行它:bash test.sh 12$1 是一个位置参数。 是的,我没注意到。对不起:)【参考方案2】:

因为大括号扩展发生在变量扩展之前。 http://www.gnu.org/software/bash/manual/bashref.html#Brace-Expansion.

如果你想使用大括号,你可以这样冷酷:

for i in `eval echo 1..$1`;
do
    echo $1 $i;
done

总结:Bash 是邪恶的。

【讨论】:

嘿,答案+1,卑鄙-0.5。 @glennjackman:哇,你是说 Bash 的无数扩展和转义规则不卑鄙? 我对涉及eval 的答案说 +1 感到很脏。回复:邪恶:bash 不卑鄙,但有点像直接喝谷物酒。有些人似乎喜欢它,但一开始很难不窒息,而且你做的越多,你就越不被它打扰。 @Sorpigal:那一定是我。我几乎每天都在使用它,但它仍然困扰着我......(但我也不擅长使用纯酒精) 这仍在工作并解决问题。谢谢!【参考方案3】:

你可以使用seq命令:

for i in `seq 1 $1`

或者你可以使用C风格的for...loop

for((i=1;i<=$1;i++))

【讨论】:

C 风格的 for 循环优于外部 seq 命令。【参考方案4】:

这是一种在大括号内展开变量的方法无需 eval

end=3
declare -a 'range=('"1..$end"')'

我们现在有一个很好的数字数组:

for i in $range[@];do echo $i;done
1
2
3

【讨论】:

【参考方案5】:

我知道您在标题中提到了 bash,但我想补充一点,“for i in $1..$2”在 zsh 中按预期工作。如果您的系统安装了 zsh,您只需将 shebang 更改为 zsh。

将 zsh 与示例 'for i in $1..$2' 一起使用还具有额外的好处,即 $1 可以小于 $2 并且它仍然有效,如果你想要的话,这需要相当多的混乱一种 C 风格的 for 循环的灵活性。

【讨论】:

以上是关于在大括号扩展范围中使用变量馈送到 for 循环的主要内容,如果未能解决你的问题,请参考以下文章

c++、java、C#之间的for循环初始化变量范围

在 bash for 循环中使用命令行参数范围打印包含参数的括号

循环语句while与for的穷举迭代

C++-----基于范围的for循环

for循环中的作用域 闭包

是否可以在for循环中声明两个不同类型的变量?