Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 如何按行长度排序文件,然后按字母顺序排序第二个键?_Bash_Sorting - Fatal编程技术网

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

Bash 如何按行长度排序文件,然后按字母顺序排序第二个键?,bash,sorting,Bash,Sorting,假设我有一个文件: ab aa c aaaa 我希望它能像这样分类 c aa ab aaaa 也就是按行长排序,然后按字母顺序排序。在bash中可能吗?您可以为每一行预先指定行的长度,然后进行数字排序,最后删除数字

假设我有一个文件:

ab
aa
c
aaaa
我希望它能像这样分类

c
aa
ab
aaaa

也就是按行长排序,然后按字母顺序排序。在bash中可能吗?

您可以为每一行预先指定行的长度,然后进行数字排序,最后删除数字

我不认为行可以以数字开头,所以我希望sort-n能起作用,因为如果所有字符串的长度都相同,字母和数字排序会给出相同的结果,因为我们是按我通过awk添加的行长度排序的

事实证明,即使您的输入有以数字开头的行,一切都能正常工作,原因是排序为-n

在行的前导数字部分进行数字排序; 如果系结,则使用strcmp对整条线路进行比较 下面是一些演示:

$echo-e'3 11\n3 2'|排序-n 3 11 3 2 两行上的'3'使它们在数字排序时相等 但是'3 11'在'3 2'之前,由'strcmp'在'1'在'2'之前` $echo-e'3 11\n03 2'|排序-n 03 2 3 11 '03'对'3'是一个数字平局, 但是'03 2'由'strcmp'排在'3 11'之前,因为'0'排在'3'之前` 幸运的是,awk命令中包含的,I插入了一个空格,实际上是OFS,即非数字,从而打破了数字排序,并让strcmp排序在比较数字相等的整行上起作用,在这种情况下

我不知道这个行为是否是POSIX,但我使用的是GNU coreutils 8.32的排序。有关详细信息,请参阅和


awk可以自己完成所有工作,但我认为使用sort-to-sort更习惯于使用sort-to-sort和高效,正如在一篇评论中所解释的那样,毕竟,为什么您不认为sort是shell中用于排序的性能最好的工具?

您可以为每一行预先指定行的长度,然后进行数字排序,最后把数字删掉

我不认为行可以以数字开头,所以我希望sort-n能起作用,因为如果所有字符串的长度都相同,字母和数字排序会给出相同的结果,因为我们是按我通过awk添加的行长度排序的

事实证明,即使您的输入有以数字开头的行,一切都能正常工作,原因是排序为-n

在行的前导数字部分进行数字排序; 如果系结,则使用strcmp对整条线路进行比较 下面是一些演示:

$echo-e'3 11\n3 2'|排序-n 3 11 3 2 两行上的'3'使它们在数字排序时相等 但是'3 11'在'3 2'之前,由'strcmp'在'1'在'2'之前` $echo-e'3 11\n03 2'|排序-n 03 2 3 11 '03'对'3'是一个数字平局, 但是'03 2'由'strcmp'排在'3 11'之前,因为'0'排在'3'之前` 幸运的是,awk命令中包含的,I插入了一个空格,实际上是OFS,即非数字,从而打破了数字排序,并让strcmp排序在比较数字相等的整行上起作用,在这种情况下

我不知道这个行为是否是POSIX,但我使用的是GNU coreutils 8.32的排序。有关详细信息,请参阅和


awk可以自己完成所有工作,但我认为使用sort-to-sort更习惯于使用sort-to-sort和高效,正如在一篇评论中所解释的,毕竟,为什么您不认为sort是shell中用于排序的性能最好的工具呢?

使用gawk-zero-filled将行的长度插入到四个位置,这样它就能正确排序,按两个键排序,首先是长度,然后是行上的第一个单词,然后删除长度:

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)

使用gawk zero filled将行的长度插入到四个位置,以便正确排序,先按两个键排序长度,然后按行上的第一个单词排序,然后删除长度:

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)
对于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
对于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

我们鼓励提问者展示他们迄今为止为自己解决问题所做的努力。@Anush:别忘了接受其中一个答案!我们鼓励提问者展示他们迄今为止为自己解决问题所做的努力。@Anush:别忘了接受其中一个答案!排序更惯用。。。。我认为这不是真正的争论。然而,sort可以很好地处理大型文件,而使用awk时,如果您想使用内置的awk,所有内容都必须放入内存中;如果你走到这一步,我甚至不会使用awk,而是像Perl或Ruby这样的东西,这会更有用
合适的所以最后,这对我来说是一个支持使用…|的论点排序顺便说一句,在您的解决方案中,您应该将多键排序放在代码示例中,因为OP要求对于等长键,排序应该按字母顺序进行。@user1934428,请查看您现在是否喜欢它。至于Ruby和Perl,我不了解它们,所以我甚至不知道它们的性能如何。我想你可以加上另一个答案。在打成平局的情况下,它会继续使用基于行的其余部分的字母排序:我不认为这是真的。事实上,顺序是未指定的,仅在您的示例中发生,但在一般情况下可能会中断。为了证明这一点,我添加了选项-s,它表示如果您不能根据提供的排序标准做出决定,请保持原始顺序:echo3B;回声3 a |排序-n-s。实际上,我认为你最初指定两个排序键的想法比较好。请参阅USER 1934 428,请考虑我编辑的答案。我明白了!谢谢你再次明确地指出这一点。排序更为惯用。。。。我认为这不是真正的争论。然而,sort可以很好地处理大型文件,而使用awk时,如果您想使用内置的awk,所有内容都必须放入内存中;如果你走到这一步,我甚至不会使用awk,而是使用Perl或Ruby之类的东西,这更合适。所以最后,这对我来说是一个支持使用…|的论点排序顺便说一句,在您的解决方案中,您应该将多键排序放在代码示例中,因为OP要求对于等长键,排序应该按字母顺序进行。@user1934428,请查看您现在是否喜欢它。至于Ruby和Perl,我不了解它们,所以我甚至不知道它们的性能如何。我想你可以加上另一个答案。在打成平局的情况下,它会继续使用基于行的其余部分的字母排序:我不认为这是真的。事实上,顺序是未指定的,仅在您的示例中发生,但在一般情况下可能会中断。为了证明这一点,我添加了选项-s,它表示如果您不能根据提供的排序标准做出决定,请保持原始顺序:echo3B;回声3 a |排序-n-s。实际上,我认为你最初指定两个排序键的想法比较好。请参阅USER 1934 428,请考虑我编辑的答案。我明白了!谢谢你再次明确指出这一点。