Awk, in this case, particularly, gawk, has supported multidimensional arrays for a long time. On linux, 'awk' is usually 'gawk', so the distinction isn't important.
You can see one manual entry here:
https://www.gnu.org/software/gawk/manual/html_node/Arrays-of-Arrays.html
It seems there are two mechanisms. In the case of:
X[a,b]
awk (gawk) it uses a separator character, known as 'SUBSEP'. So you can get 'a' and 'b' above by:
split(X,x_bits,SUBSEP);
gawk also provides 'true' arrays. What I'm trying to understand is the difference between these. The manual page is:
Arrays
Arrays are subscripted with an expression between square brackets ([ and ]). If the expression is an expression list (expr, expr ...) then the array subscript is a string con
sisting of the concatenation of the (string) value of each expression, separated by the value of the SUBSEP variable. This facility is used to simulate multiply dimensioned
arrays. For example:
i = "A"; j = "B"; k = "C"
x[i, j, k] = "hello, world\n"
assigns the string "hello, world\n" to the element of the array x which is indexed by the string "A\034B\034C". All arrays in AWK are associative, i.e., indexed by string values.
The special operator in may be used to test if an array has an index consisting of a particular value:
if (val in array)
print array[val]
If the array has multiple subscripts, use (i, j) in array.
The in construct may also be used in a for loop to iterate over all the elements of an array. However, the (i, j) in array construct only works in tests, not in for loops.
An element may be deleted from an array using the delete statement. The delete statement may also be used to delete the entire contents of an array, just by specifying the array
name without a subscript.
gawk supports true multidimensional arrays. It does not require that such arrays be ``rectangular'' as in C or C++. For example:
a[1] = 5
a[2][1] = 6
a[2][2] = 7
NOTE: You may need to tell gawk that an array element is really a subarray in order to use it where gawk expects an array (such as in the second argument to split()). You can do
this by creating an element in the subarray and then deleting it with the delete statement.
The version is:
$ awk -V
GNU Awk 4.1.4, API: 1.1 (GNU MPFR 3.1.5, GNU MP 6.1.2)
---------- Post updated at 01:37 PM ---------- Previous update was at 01:06 PM ----------
OK, I think I've worked out the answer.
The two types of array are entirely different and incompatible. You cannot use split if you define the array as X[a][b][c].
It does allow you to mix the two types, as in X[a][b,c], as I did, but it is a really bad idea to do this as it seems to confuse the interpreter - this was my problem.
Here is some working code that sets up, then lists, the elements in the three dimensional array correctly - no use of split and it's OK.
BEGIN {
Z[1]["Jim"]["The quick brown fox jumps over the lazy dogs"]=42;
Z[1]["Harry"]["Colorless green ideas sleep furiously"]=41;
Z[2]["Jack"]["The quick brown foxes jumps over the lazy dogs"]=40;
Z[2]["Harry"]["Colorless green ideas sleep furiously"]=39;
Z[3]["Joe"]["The quick brown foxes jumps over the lazy dog"]=38;
Z[4]["James"]["The quick brown fox jumps over a lazy dog"]=37;
Z[5]["Jimmy"]["The quick brown fox jumps over the lazy dog again"]=36;
}
END {
print "Z[a,b,c]";
for ( a in Z )
for ( b in Z[a] )
for ( c in Z[a] )
print "a of Z[a]: " a "\t| b of Z[a] :\t" b "\t| c of Z[a][c]:\t" c " |\t\tvalue of Z[a][c]:\t" Z[a][c];
}
Output:
$ awk -f demo.awk </dev/null
Z[a,b,c]
a of Z[a]: 1 | b of Z[a] : Harry | c of Z[a][c]: Colorless green ideas sleep furiously | value of Z[a][c]: 41
a of Z[a]: 1 | b of Z[a] : Jim | c of Z[a][c]: The quick brown fox jumps over the lazy dogs | value of Z[a][c]: 42
a of Z[a]: 2 | b of Z[a] : Harry | c of Z[a][c]: Colorless green ideas sleep furiously | value of Z[a][c]: 39
a of Z[a]: 2 | b of Z[a] : Jack | c of Z[a][c]: The quick brown foxes jumps over the lazy dogs | value of Z[a][c]: 40
a of Z[a]: 3 | b of Z[a] : Joe | c of Z[a][c]: The quick brown foxes jumps over the lazy dog | value of Z[a][c]: 38
a of Z[a]: 4 | b of Z[a] : James | c of Z[a][c]: The quick brown fox jumps over a lazy dog | value of Z[a][c]: 37
a of Z[a]: 5 | b of Z[a] : Jimmy | c of Z[a][c]: The quick brown fox jumps over the lazy dog again | value of Z[a][c]: 36