1

I have the following sample code for my shell script:

#!/bin/bash

x[1,1]=0
x[2,1]=1

echo "x[1,1]=${x[1,1]}"
echo "x[2,1]=${x[2,1]}"

for i in {1..2}; do
    x[$i,1]=${i}
    echo "loop$i x[$i,1]=${i}"
done

echo "x[1,1]=${x[1,1]}"
echo "x[2,1]=${x[2,1]}"

and I am expecting for x[1,1] to have the value of 1 and x[2,2] to have the value of 2.

But when I run the script the result is:

$ ./test3.sh    
x[1,1]=1    
x[2,1]=1    
loop1 x[1,1]=1    
loop2 x[2,1]=2
x[1,1]=2    
x[2,1]=2

I expect x[1,1] to retain the value of 1 but it happens to be 2 now. Is there something wrong with my script?

0

1 Answer 1

2

Bash does not have 2-D arrays. The best you can do is emulate them with associative arrays.

Add the following line to the beginning of your script:

declare -A x

This makes x into an associative array. When that is done, the script produces the output that you expect:

$ bash script
x[1,1]=0
x[2,1]=1
loop1 x[1,1]=1
loop2 x[2,1]=2
x[1,1]=1
x[2,1]=2

Bash indexed arrays

Unless declare -A is used, a bash array is just an indexed array. Let's define y as an indexed array:

$ y=()

Now, let's assign two values:

$ y[2,3]=1
$ y[22,3]=2

Now, let's use declare -p to find out what the contents of the array really are:

$ declare -p y
declare -a y='([3]="2")'

As you can see, there is only y[3]. The reason is that the index in an indexed array is subject to arithmetic expansion and, when given a list of comma-separated values, arithmetic expansion returns just the last one.

In other words, as far as bash is concerned, assignments to y[2,3] and y[22,3] are both just assignments to y[3]. The second assignment overwrites the first.

We can see this directly if we echo the results of arithmetic expansion:

$ echo $((3))
3
$ echo $((2,3))
3
$ echo $((22,3))
3

When given a list of comma-separated values, arithmetic expansion returns the last one. This is true even if the comma-separated list is a long one:

$ echo $((1+2,3*4,5,6,7,8))
8

It is always the last value which is returned.

Bash associative arrays

Let's examine what happens with associative arrays. Let's define z as an associative array and assign some values to it:

$ declare -A z
$ z[1,2]=1
$ z[3,4]=2
$ z["Jim Bob"]=3

Now, let's see what was stored in z:

$ declare -p z
declare -A z='([3,4]="2" ["Jim Bob"]="3" [1,2]="1" )'

This seems to be what you need.

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

1 Comment

Thanks! declare -A did the job. I have rechecked other posts I saw about 2d arrays for shell, and I have overlooked declare

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.