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()ing keys[] чтобы получить:
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 меньше, чем число. число 888, что в данном случае ИМХО является желаемым результатом.
person
Ed Morton
schedule
17.07.2013
asort()
последний аргумент может быть определяемой пользователем функцией сравнения. Вы можете написать свою собственную логику. кроме того, вы можете превратить двумерный массив в одномерный массив и использовать встроенную функцию asort(). что ты уже испробовал? - person Kent   schedule 17.07.2013