在awk中同时排序多个数组

时间:2013-06-06 22:40:51

标签: sorting awk gawk

简介

请考虑以下示例sort.awk

BEGIN {
    a[1]="5"; 
    a[2]="3";
    a[3]="6";

    asort(a)
    for (i=1; i<=3; i++) print a[i]
}

使用awk -f sort.awk运行以升序排列数组a中的已排序数字:

3
5
6

问题

考虑扩展的两个案例(通常,对于N)相应的数组ab

a[1]="5"; b[1]="fifth"
a[2]="3"; b[2]="third"
a[3]="6"; b[3]="sixth"

以及“同时”排序所有数组的问题。为了实现这一点,我需要对数组a进行排序,同时也需要获取排序的索引。对于这个简单的情况,索引将由

给出
ind[1]=2; ind[2]=1; ind[3]=3;

有了这些索引,我可以根据数组b的排序结果打印出已排序的a数组。例如:

for (i=1;i<=3;i++) print a[ind[i]], b[ind[i]]

将打印已排序的数组..

另见Sort associative array with AWK

2 个答案:

答案 0 :(得分:2)

我提出了两种方法来进行“同步”排序。

  • 一个是组合两个数组然后排序。当您只需要输出时,这很有用。

  • 另一个人正在使用gawk的asorti()

阅读代码了解详情,我认为很容易理解:

BEGIN{
    a[1]="5"; b[1]="fifth"
    a[2]="3"; b[2]="third"
    a[3]="6"; b[3]="sixth"

    #method 1: combine the two arrays before sort
    for(;++i<=3;)
        n[i] = a[i]" "b[i]
    asort(n)
    print "--- method 1: ---"
    for(i=0;++i<=3;)
        print n[i]

    #method 2:
    #here we build a new array/hastable, and use asorti()
    for(i=0;++i<=3;)
        x[a[i]]=b[i]

    asorti(x,t)
    print "--- method 2: ---"
    for(i=0;++i<=3;)
        print t[i],x[t[i]]
}

输出:

kent$  awk -f sort.awk
--- method 1: ---
3 third
5 fifth
6 sixth
--- method 2: ---
3 third
5 fifth
6 sixth

修改

如果要获取原始索引,可以按以下方式尝试方法3:

#method 3: 
print "--- method 3: ---"
for(i=0;++i<=3;)
    c[a[i]] = i;

asort(a)
for(i=0;++i<=3;)
    print a[i], " | related element in b: "b[c[a[i]]], " | original idx: " c[a[i]] 

输出是:

--- method 3: ---
3  | related element in b: third  | original idx: 2
5  | related element in b: fifth  | original idx: 1
6  | related element in b: sixth  | original idx: 3
你可以看到,原来的idx就在那里。如果要将它们保存到数组中,只需在for循环中添加idx[i]=c[a[i]]

<强> EDIT2

方法4:结合不同的顺序,然后拆分得到idx数组:

#method 4:

for(i=0;++i<=3;)
    m[i] = a[i]"\x99"i 
asort(m)
print "--- method 4: ---"
for(i=0;++i<=3;){
    split(m[i],x,"\x99")
    ind[i]=x[2]
    }

#test ind array:
for(i=0;++i<=3;)
    print i"->"ind[i]

输出:

--- method 4: ---
1->2
2->1
3->3

答案 1 :(得分:0)

根据Kent的回答,这里有一个解决方案,也应该获得索引:

BEGIN {
    a[1]="5";
    a[2]="3";
    a[3]="6";

    for (i=1; i<=3; i++) b[i]=a[i]" "i
    asort(b)
    for (i=1; i<=3; i++) {
      split(b[i],c," ")
      ind[i]=c[2]
    }
    for (i=1; i<=3; i++) print ind[i]
}