Reputation: 59
I would like to write a for in loop in which the possible values are taken from another variable. The part that I can't figure out is how to include values that need brace expansion. For example:
TEXT="a b c d{a..c} e f"
for VAR in $TEXT; do echo $VAR; done
What i get is
a
b
c
d{a..c}
e
f
But what I want is
a
b
c
da
db
dc
e
f
Does anyone know how I can get this to work?
Thank you very much!
Upvotes: 1
Views: 3160
Reputation: 2734
EDIT
While there's a time & place for eval
, it's not the safest approach for the general case. See Why should eval be avoided in Bash, and what should I use instead? for some reasons why.
Use eval
:
TEXT="a b c d{a..c} e f"
for VAR in $TEXT; do eval echo $VAR; done
Output:
a
b
c
da db dc
e
f
If you want to loop over every element, you'll have to nest your loops:
for VAR in $TEXT; do
for VAR2 in $(eval echo $VAR); do
echo $VAR2
done
done
Output:
a
b
c
da
db
dc
e
f
Or use the eval on TEXT
rather than each element:
TEXT="$(eval echo "a b c d{a..c} e f")"
for VAR in $TEXT; do echo $VAR; done
Output:
a
b
c
da
db
dc
e
f
Upvotes: 2
Reputation: 52431
Without eval
, but with command substitution:
$ text="$(echo a b c d{a..c} e f)"
$ echo "$text"
a b c da db dc e f
And, as mentioned in Tom's answer, an array is probably the better way to go here.
Upvotes: 0
Reputation: 74685
I fear that you may have to resort to using eval
in this case...However, I'd suggest that you avoided using a loop:
eval "printf '%s\n' $TEXT"
Using eval
means that the braces will be expanded, producing your desired outcome.
You can see what happens using set -x
:
$ set -x
$ eval "printf '%s\n' $TEXT"
+ eval 'printf '\''%s\n'\'' a b c d{a..c} e f'
++ printf '%s\n' a b c da db dc e f
a
b
c
da
db
dc
e
f
Note that the expansion occurs before the list is passed as arguments to printf
.
If you get to define $TEXT
yourself and want to loop through each of its expanded elements, I'd suggest using an array instead:
text=( a b c d{a..c} e f )
for var in "${text[@]}"; do
# whatever with "$var"
done
This is the preferred solution as it doesn't involve using eval
.
Upvotes: 5