FWIW、これが回避策の「sort_by()」関数です。
$ 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
############################
最初にこれを変換することで機能します:
a[1][1] = "dog"
a[1][2] = 999
a[2][1] = "mouse"
a[2][2] = 777
a[3][1] = "bird"
a[3][2] = 888
これに:
keys[1] = 999
vals[999] = dog SUBSEP 999
keys[2] = 777
vals[777] = mouse SUBSEP 777
keys[3] = 888
vals[888] = bird SUBSEP 888
次に、キー[]をasort()して次を取得します。
keys[1] = 777
keys[2] = 888
keys[3] = 999
次に、元の配列を再設定するために、キー配列の要素を vals 配列のインデックスとして使用して、キー配列をループします。
並べ替えたい値をインデックスとして使用してから asorti() を実行しなかった理由を疑問に思っている人がいる場合は、コードが少し簡潔になるので、その理由を次に示します。
$ 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
asorti() は、"9" を "888" よりも高い値として扱うことに注意してください。これは、asorti() が配列インデックスでソートし、すべての配列インデックスが (数字のように見えても) 文字列であり、アルファベット順で文字列 "9" の最初の文字が文字列 "888" の最初の文字よりも大きいためです。一方、asort() は配列の内容を並べ替えます。配列の内容は文字列または数値である可能性があるため、通常の awk 比較規則が適用されます。数値のように見えるものはすべて数値のように扱われ、数値 9 はこの場合、私見が望ましい結果です。