我的数组中有这些字符串:
3 rere 33.33%
2 ena 22.22%
1 something 11.11%
1 som 11.11%
1 ok 11.11%
1 evo 11.11%
预期结果如下:
3 rere 33.33%
2 ena 22.22%
1 something 11.11%
1 evo 11.11%
1 som 11.11%
1 ok 11.11%
它们按编号递减排序。
我想按照中间的单词长度对它们进行排序,但如果单词长度相同,则按字母顺序排序。
这些不是专栏。
我想将它拆分为两个数组,然后对它们进行排序,但是如何将它们连接在一起? 有人有想法吗?
答案 0 :(得分:3)
您无法按sort
的长度排序。我们试试Schwartzian transform:
awk '{print length($2), $0}' file | sort -k2,2nr -k1,1nr -k3,3 | cut -d" " -f2-
awk命令需要1 something 11.11%
并输出9 1 something 11.11%
然后按数字排序第二个字段,然后按数字顺序排序第一个字段,然后排序第三个字段排序。
然后cut删除第一个字段。
答案 1 :(得分:0)
Perl救援!
perl -l -0777 -aF'\n' -ne '
print for map join(" ", @$_),
sort { $b->[0] <=> $a->[0]
|| length($a->[1]) <=> length($b->[1])
|| $a->[1] cmp $b->[1] }
map [ split ],
@F;
' input-file
-n
按记录-0777
将整个文件设置为一条记录-l
为照片添加换行符-a
拆分输入-F'\n'
告诉-a
拆分换行符<=>
)排序第0列,或按第1列的长度排序,或按字母顺序排序(cmp
)第一栏答案 2 :(得分:0)
这背后的想法与Schwartzian transform中使用的choroba's answer非常相似:我们添加一个排序字段(在本例中是第二列的长度),用它来排序,然后将其删除再次:
while read -r col1 word rest; do
printf "%d\t%s %s %s\n" "${#word}" "$col1" "$word" "$rest"
done < infile | sort -k 2,2nr -k 1,1nr -k 3,3 | cut -f 2
这导致
3 rere 33.33%
2 ena 22.22%
1 something 11.11%
1 evo 11.11%
1 som 11.11%
1 ok 11.11%
在while循环之后,输出如下所示:
4 3 rere 33.33%
3 2 ena 22.22%
9 1 something 11.11%
3 1 som 11.11%
2 1 ok 11.11%
3 1 evo 11.11%
第二列中有一个新列,其长度为字符串。它的标签分开,以便以后更容易cut
。
对于sort
,我们使用-k
参数指定要用于排序的内容(sort
并不关心字段是制表符还是空格分隔符号):2,2nr
仅使用第二个字段,数字和降序;同样适用于1,1nr
,而3,3
只是您的标准词汇排序。
输出现在看起来像这样:
4 3 rere 33.33%
3 2 ena 22.22%
9 1 something 11.11%
3 1 evo 11.11%
3 1 som 11.11%
2 1 ok 11.11%
现在我们只需要删除第一列,我们使用cut
并利用printf
引入的制表符分隔。
Bash while循环非常慢,Perl解决方案可能要快几个数量级。