任何一个给我一个SORT的解决方案

时间:2014-08-16 10:55:36

标签: linux shell sorting command

我想将数据从最短到最长的行排序,数据包含

  space ,character ,number,-,"," 

,我使用sort -n,但它没有解决这个问题。感谢您的帮助

数据

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

和我想要的结果是

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

我不在乎什么字符,只是从短到长.2行同长可以交换,这不是问题。多谢。

3 个答案:

答案 0 :(得分:2)

Perl one-liner

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

按需解释。

使用GNU awk,它非常简单:

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

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

答案 1 :(得分:1)

使用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
            }
        }
    }
}

用法:

awk -f script.awk file

输出:

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

另一个版本:

#!/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
            }
        }
    }
}

输出:

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

答案 2 :(得分:1)

试试这一次,可能会帮助你。

awk '{ print length($0) " " $0; }' $file | sort -n | cut -d ' ' -f 2-

-r选项用于撤消排序。