WarBro
WarBro

Reputation: 303

Curly brace expansion with two arrays to make every combination

I can use curly braces and the .. to make combinations as follows:

$ echo {"foo","bar"}{1..2}
foo1 foo2 bar1 bar2

If I have two arrays arr1=("foo" "bar") and arr2=(1 2), is it possible to achieve the same thing?

For example, something like:

$ echo ${arr1[@]}${arr2[@]}       # Returns "foo bar1 2"
or
$ echo {${arr1[@]}}{${arr2[@]}}   # Returns "{foo bar}{1 2}"

Upvotes: 0

Views: 194

Answers (2)

jared_mamrot
jared_mamrot

Reputation: 26675

You can do exactly what you asked for with GNU parallel:

parallel echo {} ::: "${arr1[@]}" ::: "${arr2[@]}"

(if you want the output on one line, you can pipe the output into tr -s "\n" " ": parallel echo {} ::: "${arr1[@]}" ::: "${arr2[@]}" | tr -s "\n" " "

Upvotes: 1

KamilCuk
KamilCuk

Reputation: 141533

The brace {1..2} expansion happens before variable expansion, so it's not possible to do it that way without eval.

Just iterate over two arrays and create all possible combinations

for i in "${arr1[@]}"; do
   for j in "${arr2[@]}"; do
      echo "$i$j"
    done
done

Or you can use eval. To do this safely, use printf %q to generate safely-quoted versions of your array contents, like so:

printf -v arr1_str '%q,' "${arr1[@]}"; arr1_str=${arr1_str%,}
printf -v arr2_str '%q,' "${arr2[@]}"; arr2_str=${arr2_str%,}
eval "printf '%s\n' {${arr1_str}}{${arr2_str}}"

...which you can see working (with some intentionally hostile/tricky sample data) at https://ideone.com/HunmC3

Upvotes: 2

Related Questions