1

If I do this, I get the result as expected.

for i in {125..129}; do echo $i; done
125
126
127
128
129

But when I do this? I get something weired.

for i in {$((1+(25-1)*500))..$((25*500))}; do echo $i; done

{12001..12500}

I wish to pass a variable inside the loop variables like $((1+($j-1)*500))

Linguist
  • 123
  • 1
  • 10

6 Answers6

3

Bash's brace expansion has limitations. What you want is seq:

for i in $( seq $((1+(25-1)*500)) $((25*500)) ); do echo $i; done

The above will loop over all numbers from 12001 to 12500.

Discussion

seq is similar to bash's braces:

$ echo {2..4}
2 3 4
$ echo $(seq 2 4)
2 3 4

The key advantage of seq is that its arguments can include not just arithmetic expressions, as shown above, but also shell variables:

$ x=4; echo $(seq $((x-2)) $x)
2 3 4

By contrast, the brace notation will accept neither.

seq is a GNU utility and is available on all linux systems as well as recent versions of OSX. Older BSD systems can use a similar utility called jot.

John1024
  • 109,961
  • 14
  • 137
  • 171
1

Brace expansion is the very first expansion that occurs, before parameter, variable, and arithmetic expansion. Brace expansion with .. only occurs if the values before and after the .. are integers or single characters. Since the arithmetic expansion in your example has not yet occurred, they aren't single characters or integers, so no brace expansion occurs.

You can force reexpansion to occur after arithmetic expansion with eval:

for i in $(eval echo {$((1+(25-1)*500))..$((25*500))}); do echo $i;
Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
1

You query is very similar to : shell script "for" loop syntax

brace expansion, {x..y} is performed before other expansions, so you cannot use that for variable length sequences.

Instead try

for i in seq $((1+(25-1)*500)) $((25*500)); do echo $i; done

Community
  • 1
  • 1
Bhindi
  • 1,403
  • 12
  • 16
0

It is just echoing the text which is exactly as it says:

{12001..12500}

That is "{"+12001+"..."+12500+"}"

Astra Bear
  • 2,646
  • 1
  • 20
  • 27
0

Don't do this with a for loop. The {..} notation is not that flexible:

i=$((1+(25-1)*500)); while test $i -le $((25*500)); do echo $((i++)); done
William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • A for loop would work (see the duplicate question), but you can't use range notation. `for i in $(seq $((1+(25-1)*500)) $((25*500))); do echo $i; done` – Josh Smeaton Feb 20 '15 at 07:06
  • You *can* use a for loop, but not with brace expansion like the op is trying to do. The only trouble with `seq` is that it is neither portable nor standard. This is merely an example to show an alternative. – William Pursell Feb 20 '15 at 14:23
0

Try this

for (( i= $((1+(25-1)*500)); i<=$((25*500)); i++ )); do echo $i; done

or this

for i in $(seq $(( 1+(25-1)*500 )) $(( 25*500 )) ); do echo $i; done