I'm able to do this properly in gawk, but when I tried to post my code to the machine where it will run, I realized it was using mawk…
$ cat multidim.gawk
# test of multidimensional arrays
// {
A[1][1]="A11"
A[1][2]="A12"
A[2][1]="A21"
A[2][2]="A22"
i=2
for ( j in A[i] )
{
print "i=" i " j=" j " A[i][j]=" A[i][j]
}
}
$ echo hi | awk -f multidim.gawk
i=2 j=1 A[i][j]=A21
i=2 j=2 A[i][j]=A22
seems mawk has a different idea about how multidimensional arrays should work. When I run it on Debian with mawk, I get a syntax error. A[i,j] seems the correct syntax, and it 'synthesizes' multidimensional arrays.
So I tried two things, neither work:
$ cat multidim.mawk
// {
A[1,1]="A11"
A[1,2]="A12"
A[2,1]="A21"
A[2,2]="A22"
i=2
for ( j in A[i] )
{
print "i=" i " j=" j "a[i,j]=" a[i,j]
}
}
$ echo hi | awk -f multidim.mawk
awk: multidim.mawk: line 9: syntax error at or near [
Seems sensible, using a 1dim array index on a "multidimensional" array generates an error.
Trying to just walk the WHOLE array so that I can use an if statement to selct the first dimension even (extremely inefficient and horrible)… but I can't even do that!:
$ cat multidim2.mawk
# test of multidimensional arrays
// {
A[1,1]="A11"
A[1,2]="A12"
A[2,1]="A21"
A[2,2]="A22"
for ( (i, j) in A )
{
print "i=" i " j=" j "a[i,j]=" a[i,j]
}
}
$ echo hi | awk -f multidim2.mawk
awk: multidim2.mawk: line 8: syntax error at or near )
Is there any way to walk a multidimensional array in mawk?
Is there a language reference other than the mawk manpage?
Thanks!
Best Answer
mawk
(andnawk
) provide only synthesised multi-dimensional arrays.gawk
provides (since 4.0, thx manatwork) true multi-dimensional arrays,though the man page (IMHO) misdirects a little: immediately after introducing(fixed since v4.1.1!).if ((i,j) in array)
it follows with "The in construct may also be used in a for loop to iterate over all the elements of an array."But,
for ((i,j) in array)
is not the way to iterate over these, thegawk
way is (as you used originally):With
nawk
/mawk
you are stuck with synthesised multi-dimensional arrays, soNow, your next problem is going to be ordering, array indexes are implicitly string type, and arrays are implicitly unordered. Unless you have separate knowledge of the indexes, as would be the case with a simple non-sparse array with consecutive integer indexes from 0..N.
gawk
offers a solution for an orderedin
.If you know the indexes of a synthesised array, then you can use
A[i,j]
(which is treated asA[i SUBSEP j]
), orfor
/in
and some string splitting to rebuild the list ofi
andj
, orif ((i,j) in A)
(test for presence, without autovivification of indexes).In
gawk
you cannot use(i,j) in arr
where arr is a true multi-dimensional array, you need to break it into two (or however many dimensions)for
loops as above. To be fully correct though, the inner loop(s) should contain anisarray()
condition, since it's not required that every element ofarr[i]
in turn be an array, gawk is happy to allow scalars too.I know of no
mawk
specific documentation other than the man page, it aims to be a standard newawk
(i.e.nawk
) implementation (so no true multi-dimensional arrays, no index sorting, and noisarray()
).