1

I know that in bash:

declare array=(hei{1,2}_{1,2})

will create an array with a list of elements:

echo ${array[*]}
hei1_1 hei1_2 hei2_1 hei2_2

but I would like to use variables in the array declaration,too:

var=1,2
declare array=(hei{$var}_{$var})

But it does not work:

echo ${array[*]}
hei{1,2}_{1,2}

Please help. I find very frustrating to specify something like hei{1,2}_{a,b,c}..n times..{hei,hei} in a code.

Thanks in advance

NOTE: It is possible in zsh without eval (got it from stackexchange.com): e.g., this script would do what i need, but in zsh (which I cannot always use):

#!/usr/bin/zsh
var1=( a c  )
var2=( 1 2  )
arr=($^var1$^var2)
printf "${arr[*]}"
2
  • 2
    FYI, ${array[*]} turns your array into a string, and since that string is unquoted, string-splits it and expands any globs within. Using printf '%q\n' "${array[@]}" is a safer, more accurate way to display the contents of an array, since it shows you the difference between array=( "hello world" ), array=( hello world ), and array=( hello $'world\r' ). Commented Sep 26, 2014 at 19:35
  • Thanks Charles Duffy. I cannot upvote, but thanks :) Commented Sep 29, 2014 at 13:54

2 Answers 2

3

Brace expansion cannot be used with variables unless you also use eval, because brace expansion occurs before parameter expansion does.

The safe approach (no eval) is thus to not use brace expansion at all:

var=1,2
IFS=, read -r -a var_values <<<"$var"
result=( )
for val1 in "${var_values[@]}"; do
  for val2 in "${var_values[@]}"; do
    result+=( "hei${val1}_${val2}" )
  done
done

The unsafe approach is something like this:

var=1,2
eval "array=( hei{$var}_{$var} )"

DO NOT follow the latter practice unless you trust your inputs.

Sign up to request clarification or add additional context in comments.

2 Comments

Every cloud has a silver lining: I think Shellshock will make lots of people think twice before using eval on their variables. For a while, at least. :)
Thanks, this works :) I am still not familiar with the order in expansion. In this specific case I trust my inputs, and therefore I am tempted to use eval (and thus it is also the reason why I did not care about using "echo" and quoting them). But to avoid future bugs, I will use the safe approach.
0

Could try something like this...

var=1,2
declare -a array

IFS=','
for item in ${var}; do
array[${#array[@]}]="$item";
done

1 Comment

Sorry, maybe there was a misunderstanding: what you suggest is the same as to do declare -a array=(1 2). Instead, I want the all possible combination of the numbers, like declare -a array=(11 12 21 22).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.