Bash 按任何字段中的最高值排序
我想根据第2-8列中的值对文件进行排序? 基本上,我希望根据这些字段中任何一行中出现的最高值进行升序,但忽略第1、9和10列。i、 e.具有最高值的行应为文件的最后一行,第二大值应为最后一行,以此类推。。。如果升序中的下一个数字出现在多行上(如A/B),我不在乎它的打印顺序 我已经研究过如何使用排序,但找不出一种简单的方法来实现我想要的 我有点困惑,有什么想法吗 输入:Bash 按任何字段中的最高值排序,bash,sorting,awk,Bash,Sorting,Awk,我想根据第2-8列中的值对文件进行排序? 基本上,我希望根据这些字段中任何一行中出现的最高值进行升序,但忽略第1、9和10列。i、 e.具有最高值的行应为文件的最后一行,第二大值应为最后一行,以此类推。。。如果升序中的下一个数字出现在多行上(如A/B),我不在乎它的打印顺序 我已经研究过如何使用排序,但找不出一种简单的方法来实现我想要的 我有点困惑,有什么想法吗 输入: #1 2 3 4 5 6 7 8 9 10 A 0.
#1 2 3 4 5 6 7 8 9 10
A 0.00 0.00 0.01 0.23 0.19 0.07 0.26 0.52 0.78
B 0.00 0.00 0.02 0.26 0.19 0.09 0.20 0.56 0.76
C 0.00 0.00 0.02 0.16 0.20 0.22 2.84 0.60 3.44
D 0.00 0.00 0.02 0.29 0.22 0.09 0.28 0.62 0.90
E 0.00 0.00 0.90 0.09 0.18 0.05 0.24 1.21 1.46
F 0.00 0.00 1.06 0.03 0.04 0.01 0.00 1.13 1.14
G 0.00 0.00 1.11 0.10 0.31 0.08 0.64 1.60 2.25
H 0.00 0.00 1.39 0.03 0.04 0.01 0.01 1.47 1.48
I 0.00 0.00 1.68 0.16 0.55 0.24 5.00 2.63 7.63
J 0.00 0.00 6.86 0.52 1.87 0.59 12.79 9.83 22.62
K 0.00 0.00 7.26 0.57 2.00 0.64 11.12 10.47 21.59
预期产出:
#1 2 3 4 5 6 7 8 9 10
A 0.00 0.00 0.01 0.23 0.19 0.07 (0.26) 0.52 0.78
B 0.00 0.00 0.02 (0.26) 0.19 0.09 0.20 0.56 0.76
D 0.00 0.00 0.02 (0.29) 0.22 0.09 0.28 0.62 0.90
E 0.00 0.00 (0.90) 0.09 0.18 0.05 0.24 1.21 1.46
F 0.00 0.00 (1.06) 0.03 0.04 0.01 0.00 1.13 1.14
G 0.00 0.00 (1.11) 0.10 0.31 0.08 0.64 1.60 2.25
H 0.00 0.00 (1.39) 0.03 0.04 0.01 0.01 1.47 1.48
C 0.00 0.00 0.02 0.16 0.20 0.22 (2.84) 0.60 3.44
I 0.00 0.00 1.68 0.16 0.55 0.24 (5.00) 2.63 7.63
K 0.00 0.00 7.26 0.57 2.00 0.64 (11.12) 10.47 21.59
J 0.00 0.00 6.86 0.52 1.87 0.59 (12.79) 9.83 22.62
预处理数据:打印每行开头第2列到第8列的最大值,然后排序,然后删除添加的列:
awk '
NR==1{print "x ", $0}
NR>1{
max = $2;
for( i = 3; i <= 8; i++ )
if( $i > max )
max = $i;
print max, $0
}' OFS=\\t input-file | sort -n | cut -f 2-
awk'
NR==1{print“x”,$0}
NR>1{
最高=2美元;
对于(i=3;i最大值)
max=$i;
打印最大值,$0
}'OFS=\\t输入文件|排序-n |剪切-f2-
另一种纯awk变体:
$ awk 'NR==1; # print header
NR>1{ #For other lines,
a=$2;
ai=2;
for(i=3;i<=8;i++){
if($i>a){
a=$i;
ai=i;
}
} # Find the max number in the line
$ai= "(" $ai ")"; # decoration - mark highest with ()
g[$0]=a;
}
function cmp_num_val(i1, v1, i2, v2) {return (v1 - v2);} # sorting function
END{
PROCINFO["sorted_in"]="cmp_num_val"; # assign sorting function
for (a in g) print a; # print
}' sortme.txt | column -t # column -t for formatting.
#1 2 3 4 5 6 7 8 9 10
A 0.00 0.00 0.01 0.23 0.19 0.07 (0.26) 0.52 0.78
B 0.00 0.00 0.02 (0.26) 0.19 0.09 0.20 0.56 0.76
D 0.00 0.00 0.02 (0.29) 0.22 0.09 0.28 0.62 0.90
E 0.00 0.00 (0.90) 0.09 0.18 0.05 0.24 1.21 1.46
F 0.00 0.00 (1.06) 0.03 0.04 0.01 0.00 1.13 1.14
G 0.00 0.00 (1.11) 0.10 0.31 0.08 0.64 1.60 2.25
H 0.00 0.00 (1.39) 0.03 0.04 0.01 0.01 1.47 1.48
C 0.00 0.00 0.02 0.16 0.20 0.22 (2.84) 0.60 3.44
I 0.00 0.00 1.68 0.16 0.55 0.24 (5.00) 2.63 7.63
K 0.00 0.00 7.26 0.57 2.00 0.64 (11.12) 10.47 21.59
J 0.00 0.00 6.86 0.52 1.87 0.59 (12.79) 9.83 22.62
$awk'NR==1;#打印页眉
NR>1{#对于其他线路,
a=2美元;
ai=2;
对于(i=3;ia){
a=$i;
ai=i;
}
}#在行中找到最大值
$ai=“(“$ai”)”#装饰-以()
g[$0]=a;
}
函数cmp_num_val(i1,v1,i2,v2){返回(v1-v2)}排序函数
结束{
PROCINFO[“已排序”]=“cmp_num_val”#分配排序功能
对于(g中的a)打印a;#打印
}'sortme.txt | column-t#column-t用于格式化。
#1 2 3 4 5 6 7 8 9 10
A 0.00 0.00 0.01 0.23 0.19 0.07(0.26)0.52 0.78
B 0.00 0.00 0.02(0.26)0.19 0.09 0.20 0.56 0.76
D 0.00 0.00 0.02(0.29)0.22 0.09 0.28 0.62 0.90
E 0.00 0.00(0.90)0.09 0.18 0.05 0.24 1.21 1.46
F 0.00 0.00(1.06)0.03 0.04 0.01 0.00 1.13 1.14
G 0.00 0.00(1.11)0.10 0.31 0.08 0.64 1.60 2.25
H 0.00 0.00(1.39)0.03 0.04 0.01 0.01 1.47 1.48
C 0.00 0.00 0.02 0.16 0.20 0.22(2.84)0.60 3.44
I 0.00 0.00 1.68 0.16 0.55 0.24(5.00)2.63 7.63
K 0.00 0.00 7.26 0.57 2.00 0.64(11.12)10.47 21.59
J 0.00 0.00 6.86 0.52 1.87 0.59(12.79)9.83 22.62
是否可以用另一种语言(如Java)编写程序来执行此操作?不幸的是,不能。我只限于BASH…JS,C++,什么?请记住,您可以从命令行运行生成的程序!:老实说,我从来没有用过爪哇/C++,不知道第一件事…我可以使用python作为犹豫的第二选择,但我主要使用bash编写脚本。这对于标准的UNIX shell工具来说是微不足道的,不需要查看需要自己安装的内容。这太棒了!非常感谢你。非常优雅:)为什么printf“%f%s\n”,max,$0
而不是print max,$0
?为什么打印“x”$0而不是打印“x”$0?如果使用后2种方法,则更为简洁,如果另外设置了OFS='\t'
,则不需要-d'
arg作为cut
,因为tab是默认的分隔符。@EdMorton没有理由。添加了您的优秀建议。谢谢