【问题标题】:Sorting multiple arrays simultaneously in awk在 awk 中同时对多个数组进行排序
【发布时间】:2013-06-03 03:07:45
【问题描述】:

简介

考虑以下示例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;

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

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

将打印排序后的数组..

另见Sort associative array with AWK

【问题讨论】:

    标签: sorting awk gawk


    【解决方案1】:

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

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

    • 另一个是用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
    

    【讨论】:

    • 谢谢!这看起来很棒。您是否还可以使用ind[1]=2ind[2]=1ind[3]=3 获得数组ind(如我的问题)?
    【解决方案2】:

    根据Kents 的回答,这里是一个也应该获取索引的解决方案:

    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]
    }
    

    【讨论】:

    • 哈,没看到你的答案。我刚刚发布的几乎和你的方法4一样。唯一不同的是,我选择了分隔符\x99,这是一个不可见的字符,它会使解决方案更通用。 (例如,您的数组索引是字符串,并且有空格)
    猜你喜欢
    • 2014-11-10
    • 2010-09-11
    • 2011-01-28
    • 2014-06-13
    • 2015-07-02
    • 2021-11-20
    • 2015-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多