Bash 如何按行长度排序文件,然后按字母顺序排序第二个键?
假设我有一个文件:Bash 如何按行长度排序文件,然后按字母顺序排序第二个键?,bash,sorting,Bash,Sorting,假设我有一个文件: ab aa c aaaa 我希望它能像这样分类 c aa ab aaaa 也就是按行长排序,然后按字母顺序排序。在bash中可能吗?您可以为每一行预先指定行的长度,然后进行数字排序,最后删除数字
ab
aa
c
aaaa
我希望它能像这样分类
c
aa
ab
aaaa
也就是按行长排序,然后按字母顺序排序。在bash中可能吗?您可以为每一行预先指定行的长度,然后进行数字排序,最后删除数字
awk可以自己完成所有工作,但我认为使用sort-to-sort更习惯于使用sort-to-sort和高效,正如在一篇评论中所解释的那样,毕竟,为什么您不认为sort是shell中用于排序的性能最好的工具?您可以为每一行预先指定行的长度,然后进行数字排序,最后把数字删掉
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,请考虑我编辑的答案。我明白了!谢谢你再次明确指出这一点。