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

AWK sort array of strings by string length

数组是从一个split()中得到的; x=split(A,B)。 我需要按字符串的长度从最小到最大对数组进行排序。

当前订单:

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

所需订单:

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

我已经用 gawk 试过了,procinfo ["sorted in"] = "@ whatever .."。但我所取得的最大成就是按字母顺序排序。

awk的

asort()支持自定义比较函数,这样你就可以定义如何对数组进行排序

你需要一个自定义的"compare"函数,用这个比较函数做asort()

例如:

kent$  cat f
alnis nis connis

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

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

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-style" 循环或如上所述更改 PROCINFO["sorted_in"]

排序可能更容易 decorate/undecorate

$ 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([=11=])"\t"[=11=]}' | 
  sort -n | cut -f2