Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to use $var in a shell brace expansion with a range, in bash. Simply putting {$var1..$var2} doesn't work, so I went "lateral"...

The following works, but it's a bit kludgey.

# remove the split files
echo rm foo.{$ext0..$extN} rm-segments > rm-segments
source rm-segments

Is there a more "normal" way?

share|improve this question
up vote 8 down vote accepted

You may want to try :

eval rm foo.{$ext0..$extN}

Not sure whether this is the best answer, but it certainly is one.

share|improve this answer
Durrh! :( I couldn't see the obvious... Thanks :) – Peter.O Feb 21 '11 at 3:54
In bash, {} expansion happens before $ expansion, so I don't think there's any other way to do this other than using eval or some other trick to cause two passes through the expression. – mattdm Feb 21 '11 at 4:14
I just "got" it!... There is no brace expansion with {$one..$three}, because it is not a valid form of brace-expansion, which in this case expects integers... It only becomes a valid form after the $var expansion, which eval then passes through the same process to generate a normal brace sequence expansion... 1 2 3 QED ;) ... Summary: the simple presence of a brace pair does't trigger brace expansion... only a valid form triggers it. – Peter.O Feb 21 '11 at 6:49
@fred: Welcome :-) – asoundmove Feb 21 '11 at 21:48

As you already realized, {1..3} expands to 1 2 3 but {foo..bar} or {$foo..$bar} don't trigger brace expansion, and the latter is subsequently expanded to replace $foo and $bar by their values.

A fallback on GNU (e.g. non-embedded Linux) is the seq command.

for x in `seq $ext0 $extN`; do rm foo.$x; done

Another possibility. if foo. contains no shell special character, is

rm `seq $ext0 $extN | sed 's/^/foo./'`

The simplest solution is to use zsh, where rm foo.{$ext0..$extN} does what you want.

share|improve this answer
Thanks for the options.. It's good to see them all grouped .. I'll stick with bash and eval... eval is simple enough now that I know what's going on behind the scenes; so it's no longer a problem. No need to change a good horse because of the rider :)... – Peter.O Feb 22 '11 at 4:36

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.