web-dev-qa-db-ja.com

forループに供給されるブレース拡張範囲で変数を使用する

ここに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}を直接記述した場合と同じように動作しないのはなぜですか?

46
spraff

これを行うには、Cスタイルのforループを使用する必要があります。

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

これにより、外部コマンドや厄介なevalステートメントが回避されます。

67
jordanm

中括弧の展開は変数の展開の前に発生するためです。 http://www.gnu.org/software/bash/manual/bashref.html#Brace-Expansion

中かっこを使用する場合は、次のような厳しいものになる可能性があります。

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

要約:Bashは下品です。

27

seqコマンドを使用できます。

for i in `seq 1 $1`

または、Cスタイルfor...loopを使用できます。

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

中括弧内の変数を展開する方法を次に示しますevalなし

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

これで、素敵な数字の配列ができました。

for i in ${range[@]};do echo $i;done
1
2
3
2
Jonathan Cross

見出しでbashについて言及していることは知っていますが、 'for i in {$ 1 .. $ 2}'はzshで意図したとおりに動作することを付け加えます。システムにzshがインストールされている場合、Shebangをzshに変更するだけです。

'for i in {$ 1 .. $ 2}'の例でzshを使用すると、$ 1が$ 2未満でも機能するという追加の利点があります。このような柔軟性が必要な場合は、かなりの混乱が必要になります。 Cスタイルのforループを使用します。

1
Joshua