Skip to main content
2 of 4
added 16 characters in body
mattmc3
  • 467
  • 4
  • 9

It's hacky, but you can serialize an array with typeset -p. Using that strategy, you can make an array of serialized arrays in bash, and then eval them. Notice that we have to use quoting if we care about empty strings as values:

# multidimensional array of red, yellow, and green things
# serialized with `typeset -p`
# red, yellow, green things
typeset -a color_table=(
  "$(inner_row=(stop caution go);          typeset -p inner_row)"
  "$(inner_row=(rose tulip clover);        typeset -p inner_row)"
  "$(inner_row=(strawberry banana grape);  typeset -p inner_row)"
)

And here's how you can use that multidimensional array:

# using eval, we deserialize the inner_row variable as we loop
echo "=== table ==="
printf '%s\n' "${color_table[@]}"
echo "=== rows ==="
for row in "${color_table[@]}"; do
  eval $row
  echo "red thing: ${inner_row[0]}"
  echo "yellow thing: ${inner_row[1]}"
  echo "green thing: ${inner_row[2]}"
done

And the output is:

=== table ===
declare -a inner_row=([0]="stop" [1]="caution" [2]="go")
declare -a inner_row=([0]="rose" [1]="tulip" [2]="clover")
declare -a inner_row=([0]="strawberry" [1]="banana" [2]="grape")
=== rows ===
red thing: stop
yellow thing: caution
green thing: go
red thing: rose
yellow thing: tulip
green thing: clover
red thing: strawberry
yellow thing: banana
green thing: grape

For Zsh users, remember arrays start at 1 so this script will work, but instead of indexing with 0-2 in this example, use 1-3.

mattmc3
  • 467
  • 4
  • 9