YOU
YOU

Reputation: 333

Any one give me a solution for SORT

I want to sort data from shortest to longest line ,the data contains

  space ,character ,number,-,"," 

,i use sort -n ,but it did not solve the job.many thanks for help

Data here

0086
0086-
0086---
0086-------
0086-1358600966
0086-18868661318
00860
00860-13081022659
00860-131111111
00860-13176880028
00860-13179488252
00860-18951041771
00861
008629-83023520
0086000
0086010-61281306

and the rerult i want is

0086
0086-
00860
00861
0086000
0086---
0086-------
0086-1358600966
00860-131111111
008629-83023520
0086-18868661318
0086010-61281306
00860-13081022659
00860-13176880028
00860-13179488252
00860-18951041771

I do not care what characters ,just from short to long .2 lines with the same long can exchange ,it is not a problem .many thanks

Upvotes: 0

Views: 53

Answers (2)

glenn jackman
glenn jackman

Reputation: 246807

Perl one-liner

perl -0777 -ne 'print join("\n", map {$_->[1]} sort {$a->[0] <=> $b->[0]} map {[length, $_]} split /\n/), "\n"' file

Explanation on demand.

With GNU awk, it's very simple:

gawk '
    {len[$0] = length($0)} 
    END {
        PROCINFO["sorted_in"] = "@val_num_asc"
        for (line in len) print line
    }
' file

See https://www.gnu.org/software/gawk/manual/html_node/Controlling-Scanning.html#Controlling-Scanning

Upvotes: 2

konsolebox
konsolebox

Reputation: 75488

Using awk:

#!/usr/bin/awk -f
(l = length($0)) && !($0 in nextof) {
    if (l in start) {
        nextof[$0] = start[l]
    } else {
        if (!max || l > max) max = l
        if (!min || l < min) min = l
        nextof[$0] = 0
    }
    start[l] = $0
    ++count[l]
}
END {
    for (i = min; i <= max; ++i) {
        if (j = count[i]) {
            t = start[i]
            print t
            while (--j) {
                t = nextof[t]
                print t
            }
        }
    }
}

Usage:

awk -f script.awk file

Output:

0086
00861
00860
0086-
0086000
0086---
0086-------
008629-83023520
00860-131111111
0086-1358600966
0086010-61281306
0086-18868661318
00860-18951041771
00860-13179488252
00860-13176880028
00860-13081022659

Another Version:

#!/usr/bin/awk -f
(l = length($0)) && !($0 in nextof) {
    if (l in start) {
        nextof[lastof[l]] = $0
    } else {
        if (!max || l > max) max = l
        if (!min || l < min) min = l
        start[l] = $0
    }
    lastof[l] = $0
    ++count[l]
}
END {
    for (i = min; i <= max; ++i) {
        if (j = count[i]) {
            t = start[i]
            print t
            while (--j) {
                t = nextof[t]
                print t
            }
        }
    }
}

Output:

0086
0086-
00860
00861
0086---
0086000
0086-------
0086-1358600966
00860-131111111
008629-83023520
0086-18868661318
0086010-61281306
00860-13081022659
00860-13176880028
00860-13179488252
00860-18951041771

Upvotes: 1

Related Questions