3

How can I use variable in for loop digits?

for example:

num="12"
for i in {0..$num}; do
        ...
done
rabotalius
  • 1,430
  • 5
  • 18
  • 27

2 Answers2

6

Brace expansion with variables doesn't work as one would expect (see Appendix B for juicy details), i.e. {0..$num} would only return {0..12} literally instead of a list of number.

Try seq instead like this:

num="12"
for i in $(seq 0 $num); do
    echo $i
done

Appendix B: Juicy details

The bash manual saith,

The order of expansions is: brace expansion, tilde expansion, parameter, variable, and arithmetic expansion and command substitution (done in a left-to-right fashion), word splitting, and filename expansion.

At the time shell expands {0..$num} (brace expansion), $num isn't expanded (variable expansion) yet. The sequence expression a..b needs both a and b to be numbers to generate a sequence, but here we have one number and one non-number (the literal string $num). Failing this, the shell falls back to interpreting {0..$num} literally. Then variable expansion takes over, and finally we get {0..12}

Community
  • 1
  • 1
doubleDown
  • 8,048
  • 1
  • 32
  • 48
  • 1
    _Brace expansion doesn't support variables_ not entirely true :) – jaypal singh Jun 27 '13 at 03:33
  • @JS웃, yeah the wording is wrong. I added a more proper explanation. – doubleDown Jun 27 '13 at 03:58
  • 1
    +1 for the update and added explanation. Though minor correction, $num will get expanded after a failed `brace expansion` reporting as `{1..12}` instead of `{1..$num}` but I guess OP will now get the bigger picture. – jaypal singh Jun 27 '13 at 03:59
2

Bash does brace expansion before variable expansion, so you will get output like {1..12}. With use of eval you can get it to work.

Test:

$ num=5
$ for i in {1..$num}; do echo "$i"; done
{1..5}
$ for i in $(eval echo {1..$num}); do echo "$i"; done
1
2
3
4
5

Please note: eval is evil in disguise.

Community
  • 1
  • 1
jaypal singh
  • 74,723
  • 23
  • 102
  • 147