Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

for loop control in bash using a string

Tags:

bash

I want to use a string to control a for loop in bash. My first test code produces what I would expect and what I want:

$ aa='1 2 3 4'
$ for ii in $aa; do echo $ii; done
1
2
3
4

I'd like to use something like the following instead. This doesn't give the output I'd like (I can see why it does what it does).

$ aa='1..4'
$ for ii in $aa; do echo $ii; done
1..4

Any suggestions on how I should modify the second example to give the same output as the first?

Thanks in advance for any thoughts. I'm slowly learning bash but still have a lot to learn.

Mike

like image 236
Mike Warrington Avatar asked Feb 12 '15 20:02

Mike Warrington


3 Answers

The notation could be written out as:

for ii in {1..4}; do echo "$ii"; done

but the {1..4} needs to be written out like that, no variables involved, and not as the result of variable substitution. That is brace expansion in the Bash manual, and it happens before string expansions, etc. You'll probably be best off using:

for ii in $(seq 1 4); do echo "$ii"; done

where either the 1 or the 4 or both can be shell variables.

like image 140
Jonathan Leffler Avatar answered Sep 20 '22 21:09

Jonathan Leffler


You could use seq command (see man seq).

$ aa='1 4'
$ for ii in $(seq $aa); do echo $ii; done
like image 21
Herman Zvonimir Došilović Avatar answered Sep 21 '22 21:09

Herman Zvonimir Došilović


Bash won't do brace expansion with variables, but you can use eval:

$ aa='1..4'
$ for ii in $(eval echo {$aa}); do echo $ii; done
1
2
3
4

You could also split aa into an array:

IFS=. arr=($aa) 
for ((ii=arr[0]; ii<arr[2]; ii++)); do echo $ii; done

Note that IFS can only be a single character, so the .. range places the numbers into indexes 0 and 2.

like image 42
Ben Grimm Avatar answered Sep 19 '22 21:09

Ben Grimm