【问题标题】:Using a variable in brace expansion range fed to a for loop在大括号扩展范围中使用变量馈送到 for 循环
【发布时间】: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 中运行。

标签: bash for-loop brace-expansion


【解决方案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 循环的灵活性。

    【讨论】:

      猜你喜欢
      • 2018-09-05
      • 1970-01-01
      • 2013-01-25
      • 1970-01-01
      • 1970-01-01
      • 2021-06-19
      相关资源
      最近更新 更多