代码之家  ›  专栏  ›  技术社区  ›  Firefly

AWK按字符串长度对字符串数组排序

  •  1
  • Firefly  · 技术社区  · 10 年前

    数组是从split()中获得的; x=拆分(A、B) . 我需要根据字符串的长度对数组进行排序,从最小到最大。

    当前订单:

    B[1]=alnis;
    B[2]=nis;
    B[3]=connis
    

    所需顺序:

    B[1]=nis;
    B[2]=alnis;
    B[3]=connis
    

    我试过用gawk,procinfo[“sorted in”]=“@whather..”。但我最大的成就是按字母顺序排序。

    3 回复  |  直到 10 年前
        1
  •  0
  •   Kent    10 年前

    asort() awk的支持自定义比较功能,因此您可以定义 怎样 对数组进行排序。

    你需要一个定制的“比较”功能 asort() 使用该比较功能。

    例如。:

    kent$  cat f
    alnis nis connis
    
    kent$  awk ' function byLength(i1,v1,i2,v2){ return length(v1)-length(v2)}
    {x=split($0, a);asort(a,b,"byLength");for(i=1;i<=x;i++)print b[i]}' f
    nis
    alnis
    connis
    
        2
  •  0
  •   Tom Fenech    10 年前

    您可以这样控制数组遍历的顺序:

    function cmp_len(i1, v1, i2, v2) {
        return length(v1) - length(v2)
    }
    
    BEGIN {
        b[1] = "alnis"
        b[2] = "nis"
        b[3] = "connis"
    
        PROCINFO["sorted_in"] = "cmp_len"
    
        for (i in b) {
            print b[i]
        }
    }
    

    我创建了自己的比较函数,并将其名称指定给 PROCINFO["sorted_in"] 以改变元素被遍历的顺序。

    测试:

    $ awk -f script.awk
    nis
    alnis
    connis
    

    您还可以将此函数的名称传递给 asort 作为第三个参数,以便将排序的值写入新数组:

    asort(b, sorted, "cmp_len")
    

    请注意,这会更改数组元素的索引,但 使用 for (i in sorted) 环要以新的顺序循环结果,您需要使用“C样式”循环或更改 PROCINFO[“sorted_in”] 如上所述。

        3
  •  0
  •   karakfa    10 年前

    排序装饰/取消装饰可能更容易

    $ echo -e "alnis\nnis\nconnis" | 
      while read -r a; do echo -e ${#a}'\t'$a; done | 
      sort -n | cut -f2
    
    nis
    alnis
    connis
    

    或者,与awk类似

    $ echo -e "alnis\nnis\nconnis" | 
      awk '{print length($0)"\t"$0}' | 
      sort -n | cut -f2