Bash doesn't natively support two-dimensional arrays, but I would like to simulate one. As a minimal working example, suppose that I have two arrays, a0
and a1
:
a0=(1 2 3 4)
a1=(5 6 7 8)
I want to write a for
loop that will print the third element of a0
and a1
. Of course, I could do this manually with two explicit calls to echo
:
echo ${a0[2]}
echo ${a1[2]}
But, I want to generalize this with a for
loop. How can I do this?
I tried the following:
for i in ${a0[@]} ${a1[@]}
do
echo {$i}[2]
echo ${i[2]}
echo ${i}[2]
echo ${$i[2]}
echo ${${i}[2]}
done
But none of those attempts are successful; I get this output:
{1}[2]
1[2]
chgreen.sh: line 30: ${$i[2]}: bad substitution
Do you have any ideas?
-
1What’s wrong with the accepted answer at the question you linked to?Scott - Слава Україні– Scott - Слава Україні2014年11月06日 01:22:51 +00:00Commented Nov 6, 2014 at 1:22
3 Answers 3
You're iterating over the wrong thing. Your for
saves each element of the array as $i
, not the array's indices. What you want is something like
#!/usr/bin/env bash
a0=(1 2 3 4)
a1=(5 6 7 8)
for ((i=0;i<${#a0[@]};i++))
do
echo ${a0[$i]} ${a1[$i]};
done
-
1You seem to be missing the point of the question. "I want to write a
for
loop that will print the third element ofa0
anda1
." The OP wants a multi-dimensional array, and he wants to be able to iterate over any index (dimension). In particular, he wants to print${a0[2]}
and${a1[2]}
in a way that would scale readily to a situation where he hasa0
,a1
,a2
,a3
,a4
, ...Scott - Слава Україні– Scott - Слава Україні2014年11月06日 01:23:39 +00:00Commented Nov 6, 2014 at 1:23 -
@Scott so you're thinking the OP wants to iterate over arrays? You are very likely right, that's not what I had understood at all. If so, your solution is just about perfect.2014年11月06日 12:01:04 +00:00Commented Nov 6, 2014 at 12:01
As you’ve presumably learned by now from your research, bash doesn’t support multi-dimensional arrays per se, but it does support "associative" arrays. These are basically indexed by a string, rather than a number, so you can have, for example,
grade[John]=100
grade[Paul]=100
grade[George]=90
grade[Ringo]=80
As demonstrated (but not explained very well) in the accepted answer of the question you linked to, indices of associative arrays can contain commas, and so a common trick is to concatenate your individual indices (0-1 ×ばつ 0-3) into a string, separated by commas. While this is more cumbersome than ordinary arrays, it can be effective:
$ declare -A a <-- Create the associative array. $ a[0,0]=1 $ a[0,1]=2 $ a[0,2]=3 $ a[0,3]=4 $ a[1,0]=5 $ a[1,1]=6 $ a[1,2]=7 $ a[1,3]=8 $ for i in 0 1> do> echo ${a[$i,2]}> done 3 <-- And here’s your output. 7
This is an odd way to do it but it might be useful in some cases. The problem is that the for
loop will resolve your arrays into their elements and treat each element separately.
Therefore, deconstruct your arrays and make them again.
a0=(1 2 3 4)
a1=(5 6 7 8)
a0=${a0[@]} # deconstruction
a1=${a1[@]}
for arr in "$a0" "$a1"; do a=( $arr ); echo ${a[2]}; done
Output
3
7