3

I'm trying to create multidimensional within arrays that are contained in an array.

tests=("'0' '1 2'" "'4' '5 6'")

in each array within tests, I want to have sub arrays. With the first array "'0' '1,2'", make another for loop to go through the contents of the sub array.

anubhava
  • 761,203
  • 64
  • 569
  • 643
Mustaf.Ahmed
  • 191
  • 2
  • 2
  • 7
  • Why are you trying to force bash to do this? bash only has one-dimensional arrays. Pick the right tool for the job. – glenn jackman Jun 29 '17 at 16:32
  • Related on unix.SE: [How can I create a multidimensional array, or something similar, with bash?](https://unix.stackexchange.com/q/741723) - as multiple people said there, if you want this, you're better off with a programming language other than the shell, such as perl or python which can still do shell-like things like easily run other programs and capture their outputs, but also have real data structures allowing arbitrary nesting of dictionaries (hashes) and lists (arrays). – Peter Cordes Apr 03 '23 at 23:24

1 Answers1

24

Since bash 4.3. (3 levels, the first contains only one element for the demo):

arr01=(0 '1 2')
arr02=(4 '5 6')
arr1=(arr01 arr02)
arr=(arr1)

declare -n elmv1 elmv2

for elmv1 in "${arr[@]}"; do
    for elmv2 in "${elmv1[@]}"; do
        for elm in "${elmv2[@]}"; do
            echo "<$elm>"
        done
    done
done

Before 4.3

arr01=(0 '1 2')
arr02=(4 '5 6')
arr1=('arr01[@]' 'arr02[@]')
arr=('arr1[@]')

for elmv1 in "${arr[@]}"; do
    for elmv2 in "${!elmv1}"; do
        for elm in "${!elmv2}"; do
            echo "<$elm>"
        done
    done
done
Nahuel Fouilleul
  • 18,726
  • 2
  • 31
  • 36
  • What's the point of the line `declare -n elmv1 elmv2`? – clime Nov 02 '20 at 05:56
  • 1
    @clime, if you have bash 4.3 or later, type `man bash` and search for `declare -n`. – linux_sa Nov 02 '20 at 22:56
  • @linux_sa Sorry, still unclear. My bash 4.3.48 man says:`...running declare -n ref=$1 inside the function creates ...`, but the answer here states `declare -n elmv1 elmv2` without the `=`. Is that the same? Quite unclear to me. And `help declare` isn't much help either: `-n make NAME a reference to the variable named by its value`. That is pretty much meaningless to me. – kebs Nov 25 '20 at 17:38
  • @kebs `/declare` below `/^SHELL BUILTIN COMMANDS` – Nahuel Fouilleul Nov 25 '20 at 19:52
  • @kebs it similar to a parameter indirection, it allow to read or write to an indirect variable, safer than using `eval` – Nahuel Fouilleul Nov 25 '20 at 20:04
  • `man bash - declare: -n Give each name the nameref attribute, making it a name reference to another variable. That other variable is defined by the value of name. All references, assignments, and attribute modifications to name, except those using or changing the -n attribute itself, are performed on the variable referenced by name's value. The nameref attribute cannot be applied to array variables.` -- But `elmv1 and v2` are arrays? – Timo Jun 07 '21 at 07:55
  • 1
    @Timo, [This answer](https://stackoverflow.com/a/40593912/1454708) seems to explain this last sentence. – Nahuel Fouilleul Jun 07 '21 at 08:26
  • 1
    `a=( 1 2 ); declare -n a=b;` --> `bash: declare: a: reference variable cannot be an array` otherwise `declare -n b=a; b=(3 4); declare -p a b` – Nahuel Fouilleul Jun 07 '21 at 08:35
  • Another issue, why is it not possible `arr1=((0 '1 2') (3 4))` - `syntax error near unexpected token ('` – Timo Jun 07 '21 at 08:40
  • indeed arrays can't be nested in the answer the name is used as reference, elmv1 is really "arr1" – Nahuel Fouilleul Jun 07 '21 at 08:42