2

The array is obtained from a split(); x=split(A,B). I need to sort the array by the length of the strings, from smallest to largest.

Current order:

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

Desired order:

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

I've tried it with gawk, procinfo ["sorted in"] = "@ whatever ..". But the most I have achieved is to sort it alphabetically.

Firefly
  • 449
  • 5
  • 20

3 Answers3

1

perhaps easier with sort 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

or, similarly with awk

$ echo -e "alnis\nnis\nconnis" | 
  awk '{print length($0)"\t"$0}' | 
  sort -n | cut -f2
karakfa
  • 66,216
  • 7
  • 41
  • 56
0

asort() of awk supports customized comparison function, so that you can define how to sort the array.

You need a customized "compare" function, and do asort() with this comparison function.

E.g.:

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
Kent
  • 189,393
  • 32
  • 233
  • 301
0

You can control the order of array traversal like this:

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

I have created my own comparison function and assigned its name to PROCINFO["sorted_in"] to alter the order in which the elements are traversed.

Testing it out:

$ awk -f script.awk
nis
alnis
connis

You can also pass the name of this function to asort as a third argument, in order to write the sorted values to a new array:

asort(b, sorted, "cmp_len")

Note that this changes the indices of the array elements but not the order in which they will be traversed with a for (i in sorted) loop. To loop through the results in the new order, you need to use a "C-style" loop or change PROCINFO["sorted_in"] as above.

Tom Fenech
  • 72,334
  • 12
  • 107
  • 141