mawk
(and nawk
) 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 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." (fixed since v4.1.1!).
But, for ((i,j) in array)
is not the way to iterate over these, the gawk
way is (as you used originally):
for (i in array)
for (j in array[i])
print array[i][j]
With nawk
/mawk
you are stuck with synthesised multi-dimensional arrays, so
for (ij in A) {
split(ij,xx,SUBSEP);
printf("A[%s,%s]=%s\n",xx[1],xx[2],A[ij])
}
Now, 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 ordered in
.
If you know the indexes of a synthesised array, then you can use A[i,j]
(which is treated as A[i SUBSEP j]
), or for
/in
and some string splitting to rebuild the list of i
and j
, or if ((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 an isarray()
condition, since it's not required that every element of arr[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 new awk
(i.e. nawk
) implementation (so no true multi-dimensional arrays, no index sorting, and no isarray()
).
Best Answer
I also don't think it's possible.
But I'll add that with busybox
awk
, variables can be both arrays and scalar. There it's OK to do:When a variable has been used as an array though,
length()
returns the number of elements in the array, even if it also has been defined as a scalar (though you can uselength(var "")
to get the length of the scalar), except when the variable has been passed as an argument to a function and assigned as a scalar there (could be considered as a bug):Too bad as otherwise it would have been easy to define a
isarray()
function there. We can still tell if a variable is an array with at least one element with(assuming the variable hasn't been defined both as an array and scalar)
In anycase, that's
busybox
awk
specific.length()
can't be used on arrays portably. One can define a portablearray_length()
function with:But that can't be used portably on non-array variables.