Can I use a variable in a Bash brace expansion?

Unfortunately, there is no way to use a variable in that expansion (AFAIK), since variable expansion happens after brace expansion.

Fortunately, there's a tool that does the same job.

for i in $(seq 1 $numlines); do
    # stuff
done

seq is from GNU coreutils; no idea how to do it in POSIX.


Sure. If you want a for loop that increments an integer variable, use the form of the for loop that increments an integer variable (or more generally performs arithmetic on the loop variable(s)).

for ((i=1; i<=numlines; i++)); do … done

This construct works in bash (and ksh93 and zsh), but not in plain sh. In plain sh, use a while loop and the test ([ … ]) construct.

i=1
while [ "$i" -le "$numlines" ]; do
  …
  i=$((i+1))
done

If you must avoid seq, which as Tom Hunt points out seems to be the usual solution to this, then an eval definitely can do it (though, I wouldn't encourage it):

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

You can stay POSIX by avoiding the {} expansion, and simply do math and integer comparisons on $numlines:

while [ ! "$numlines" -eq 0 ]; do
     echo "$numlines"
     : $((numlines-=1))
done

Outside of POSIX, bash and ksh and zsh also have C-style for loops:

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