FWIW, here's a workaround "sort_by()" function:
$ cat tst.awk
BEGIN {
a[1][1] = "dog"
a[1][2] = 999
a[2][1] = "mouse"
a[2][2] = 777
a[3][1] = "bird"
a[3][2] = 888
print "\n############################\nBefore:"
for (i=1; i in a; i++)
for (j=1; j in a[i]; j++)
printf "a[%d][%d] = %s\n",i,j,a[i][j]
print "############################"
sort_by(a,2)
print "\n############################\nAfter:"
for (i=1; i in a; i++)
for (j=1; j in a[i]; j++)
printf "a[%d][%d] = %s\n",i,j,a[i][j]
print "############################"
}
function sort_by(arr,key, keys,vals,i,j)
{
for (i=1; i in arr; i++) {
keys[i] = arr[i][key]
for (j=1; j in arr[i]; j++)
vals[keys[i]] = vals[keys[i]] (j==1?"":SUBSEP) arr[i][j]
}
asort(keys)
for (i=1; i in keys; i++)
split(vals[keys[i]],arr[i],SUBSEP)
return (i - 1)
}
$ gawk -f tst.awk
############################
Before:
a[1][1] = dog
a[1][2] = 999
a[2][1] = mouse
a[2][2] = 777
a[3][1] = bird
a[3][2] = 888
############################
############################
After:
a[1][1] = mouse
a[1][2] = 777
a[2][1] = bird
a[2][2] = 888
a[3][1] = dog
a[3][2] = 999
############################
It works by first converting this:
a[1][1] = "dog"
a[1][2] = 999
a[2][1] = "mouse"
a[2][2] = 777
a[3][1] = "bird"
a[3][2] = 888
to this:
keys[1] = 999
vals[999] = dog SUBSEP 999
keys[2] = 777
vals[777] = mouse SUBSEP 777
keys[3] = 888
vals[888] = bird SUBSEP 888
then asort()ing keys[] to get:
keys[1] = 777
keys[2] = 888
keys[3] = 999
and then looping through the keys array using it's elements as the indices to the vals array for re-populating the original array.
In case anyone's wondering why I didn't just use the values we want to sort on as indices and then do an asorti() as that would have resulted in slightly briefer code, here's why:
$ cat tst.awk
BEGIN {
a[1] = 888
a[2] = 9
a[3] = 777
b[888]
b[9]
b[777]
print "\n\"a[]\" sorted by content:"
asort(a,A)
for (i=1; i in A; i++)
print "\t" A[i]
print "\n\"b[]\" sorted by index:"
asorti(b,B)
for (i=1; i in B; i++)
print "\t" B[i]
}
$ awk -f tst.awk
"a[]" sorted by content:
9
777
888
"b[]" sorted by index:
777
888
9
Notice that asorti() treats "9" as a higher value than "888". That's because asorti() sorts on array indices and all array indices are strings (even if they look like numbers) and alphabetically the first character of the string "9" IS higher than the first character of the string "888". asort() on the other hand sorts on the contents of the array, and array contents can be strings OR numbers and so normal awk comparison rules apply - anything that looks like a number is treated like a number and the number 9 is less than the number 888 which in this case IMHO is the desired result.