【问题标题】:Using a variable in brace expansion range fed to a for loop在馈送到 for 循环的大括号扩展范围内使用变量
【发布时间】:2018-09-05 03:27:13
【问题描述】:

这是 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】:

这是一种在大括号内扩展变量的方法没有评估:

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 循环。

    【讨论】:

      猜你喜欢
      • 2012-04-12
      • 1970-01-01
      • 1970-01-01
      • 2013-01-25
      • 2012-06-12
      • 1970-01-01
      相关资源
      最近更新 更多