Multi Dimensional array

I have an array of names. Each one of the name, has a number represented to it.

For example A has an ID 8, B has an ID 2.

What I am after is a for loop that when the array is in position 1, a particular variable is set to the value of position 1 in array 2

declare -a arr=("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K")
declare -a arr2=("8" "2" "3" "4" "1" "9" "5" "6" "7" "10" "11")

for names in "${arr[@]}";
do
echo data=`grep id=$(here the value from array2) /test/test.txt`

Let's say for loop is in position 0 reading value A, therefore code should read

echo data = `grep id=8 /test/test.txt`

then when array is reading value B in position 1, array2 should read value 2. and etc.

Is there a way how this can be achieved?

Can somebody help me how this can be achieved?

why is arr needed?

arr=("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K")
arr2=("8" "2" "3" "4" "1" "9" "5" "6" "7" "10" "11")

for names in {1..${#arr2[*]}}
do
   echo data="`grep id=${arr2[(($names - 1))]} /test/test.txt`"
done

---------- Post updated at 01:26 PM ---------- Previous update was at 01:01 PM ----------

If an array was associative then keys and values can be accessed as (ex.):

arr=([A]="8" ="2" [C]="3")

for key in ${!arr[@]}
do
   echo key: $key value: ${arr[$key]}
done
1 Like

Does your shell support associative arrays as well as indexed arrays?

What shell are you using? What version of that shell are you using?

Nothing in your loop is using the values found in array arr. Why not just replace your current loop with:

for names in "${arr2[@]}";
do
echo data=$(grep "id=$names" /test/test.txt)
done

Since you haven't told us what shell you're using, the following is pure conjecture, but it will work with some shells...

If you need corresponding values from both arrays, have you considered something more like:

arr=("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K")
arr2=("8" "2" "3" "4" "1" "9" "5" "6" "7" "10" "11")
for ((i=0; i < ${#arr[@]}; i++))
do	echo "arr[$i] is ${arr[$i]}, arr2[$i] is ${arr2[$i]}"
done

(which works with recent versions of both ksh and bash )?

With both of those shells, the above script produces the output:

arr[0] is A, arr2[0] is 8
arr[1] is B, arr2[1] is 2
arr[2] is C, arr2[2] is 3
arr[3] is D, arr2[3] is 4
arr[4] is E, arr2[4] is 1
arr[5] is F, arr2[5] is 9
arr[6] is G, arr2[6] is 5
arr[7] is H, arr2[7] is 6
arr[8] is I, arr2[8] is 7
arr[9] is J, arr2[9] is 10
arr[10] is K, arr2[10] is 11
1 Like

As a bit of a digression it is also true in both bash and ksh that the index for arrays (between [ and ] ) can be an arithmetic expression.

So in the above posts ${arr2[(($names - 1))]} can be replaced with ${arr2[names-1]} and
${arr[$i]} can be replaced with ${arr}

Yes. But, ksh and bash don't handle everything used as a subscript the same way. With the following code:

abc=5
arr=(A B C D E F G H I J K)
arr2=(8 2 3 4 1 9 5 6 7 10 11)
echo ${arr[arr2[abc-1]]}

ksh version 93u+ gives me:

B

while bash version 3.2.57(1) gives me:

A

and the diagnostic:

bash: arr2: bad array subscript

To make that work correctly in both bash and ksh , I have to use:

echo ${arr[${arr2[abc-1]}]}

I believe there are other differences as well, so I tend to use more code than needed when writing array element references that I want to be portable across various shells that support arrays.

The standards don't yet specify shell array variables, so each shell decides what shortcuts, if any, can be taken when referencing arrays if that shell supports arrays at all.

Thanks for that, I can't help thinking that the bash 3.2.57(1) result is a bug.

It works fine and returns B in 4.4.12(1). Does a assignment also fail with the same error in 3.2.57(1)?

arr[arr2[abc-1]]="TEST"

The command sequence:

abc=5
arr=(A B C D E F G H I J K)
arr2=(8 2 3 4 1 9 5 6 7 10 11)

arr[arr2[abc-1]]="TEST"

printf '%s\n' "${arr[@]}"

produces the output:

A
TEST
C
D
E
F
G
H
I
J
K

with both ksh 93u+ and bash 3.2.57(1).