如何按行长度对文件进行排序,然后按第二个键的字母顺序排序?

问题描述 投票:0回答:3

假设我有一个文件:

ab
aa
c
aaaa

我希望它能像这样排序

c
aa
ab
aaaa

即按行长度排序,然后按字母顺序排序。这在 bash 中可能吗?

bash sorting
3个回答
10
投票

您可以在每行前面添加行的长度,然后进行数字排序,最后剪掉数字

< your_file awk '{ print length($0), $0; }' | sort -n | cut -f2

你看到我已经通过

sort -n
完成了排序,没有进行任何多键排序。老实说,我很幸运这有效:

  • 我不认为行可以以数字开头,所以我期望

    sort -n
    能够工作,因为如果所有字符串的长度相同,则字母和数字排序会给出相同的结果,情况就是这样,因为我们正在排序我通过 awk 添加的行长度。

  • 事实证明,即使您的输入有以数字开头的行,一切都正常,原因是

    sort -n

    1. 在行的前导数字部分上对数字进行排序;
    2. 如果有 ties,它使用
      strcmp
      来比较整行

    这是一些演示:

    $ echo -e '3 11\n3 2' | sort -n
    3 11
    3 2
    # the `3 ` on both lines makes them equal for numerical sorting
    # but `3 11` comes before `3 2` by `strcmp` before `1` comes before `2`
    
    $ echo -e '3 11\n03 2' | sort -n
    03 2
    3 11
    # the `03 ` vs `3 ` is a numerical tie,
    # but `03 2` comes before `3 11` by `strcmp` because `0` comes before `3`
    

    所以幸运的是,我在

    ,
    命令中包含的
    awk
    插入了一个空格(实际上是
    OFS
    ),即非数字,从而“破坏”了数字排序并让
    strcmp
    排序启动(在本例中,在数字比较相等的整条线上)。

    我不知道这种行为是否是 POSIX,但我正在使用

    GNU coreutils 8.32
    sort
    。有关详细信息,请参阅我的这个问题这个 Unix 上的答案

awk
可以自己完成所有工作,但我认为使用
sort
进行排序更惯用(例如,使用
sort
进行排序
)并且高效,正如评论中所解释的(毕竟,为什么你会这样做)没想到
sort
是 shell 中性能最好的排序工具?
)。


2
投票

使用

gawk
插入行的长度(将零填充到四个位置,以便正确排序),按两个键排序(首先是长度,然后是行上的第一个单词),然后删除长度:

gawk '{printf "%04d %s\n", length($0), $0}' | sort -k1 -k2 | cut -d' ' -f2-

如果一定是bash:

while read -r line; do printf "%04d %s\n" ${#line} "${line}"; done | sort -k1 -k2 | (while read -r len remainder; do echo "${remainder}"; done)

1
投票

对于 GNU awk:

$ gawk '{
    a[length()][$0]++                             # hash to 2d array
}
END {
    PROCINFO["sorted_in"]="@ind_num_asc"          # first sort on length dim
    for(i in a) {
        PROCINFO["sorted_in"]="@ind_str_asc"      # and then on data dim
        for(j in a[i])
            for(k=1;k<=a[i][j];k++)               # in case there are duplicates
                print j
        # PROCINFO["sorted_in"]="@ind_num_asc"    # I don t think this is needed?
    }
}' file

输出:

c
aa
ab
aaaa
aaaaaaaaaa
aaaaaaaaaa
© www.soinside.com 2019 - 2024. All rights reserved.