我有一个如下文件。
key1 key2 key3
a1 2 l1
a1 2.5 l2
a2 2 l2
a3 2.5 l3
a3 2.1 l4
a3 2.2 l5
我试图找到key2
满足条件key1
和key3
只发生一次的最大可能总和。对于上面的文件,我期望输出为,
a1 2 l1
a2 2 l2
a3 2.5 l3
如果我使用下面的命令,
sort -nk2 file | perl -ane '$k{$F[$1]}=$_; END{print "$k{$_}" for keys(%k)}'
我得到的输出为,
a2 2 l2
a1 2.5 l2
a3 2.5 l3
但是,我希望在输出中只获得一次key1
和key3
,并获得我在预期输出中描述的最大总和。
编辑
我有如下输入文件。
a0 11.1 l6
a0 3 l1
a1 14.0 l6
a1 2.5 l2
a2 11.1 l2
a2 2 l2
a3 13.3 l8
a3 2.1 l4
a3 2.5 l7
a4 1.6 l6
a4 1.7 l1
正如我们可以手动看到的,上述文件的最大加权输出是,
a0 11.1 l6
a2 11.1 l2
a3 13.3 l8
a4 1.7 l1
根据 Gnouc 的awk
命令,我得到的输出为:
a0 11.1 l6
a1 2.5 l2
a3 13.3 l8
a4 1.7 l1
根据 terdon 的perl
命令,我得到的输出为,
a2 2 l2
a4 1.7 l1
a3 13.3 l8
编辑3
a1 1 l1
a2 3 l2
a1 4 l3
a3 5 l2
a6 4 l5
a7 3 l2
我得到的输出为,
a3 5 l2
a6 4 l5
a7 3 l2
正如我们所看到的,l2
重复了两次。
答案1
看来您只想获得每个 的第一次出现key1
。
这将产生您预期的输出:
$ awk '!($1 in a){print;a[$1]}' file
a1 2 l1
a2 2 l2
a3 2.5 l3
更新
如果你想key1
或者 key3
应该只发生一次:
$ awk '!($1 in a) && !($3 in a){print;a[$1];a[$3]}' 1.txt
a1 2 l1
a2 2 l2
a3 2.5 l3
更新2
阅读您的评论后,我认为解决方案如下:
$ sort -rnk2 file | awk '!a[$1]++' | awk '!a[$3]++'
a1 14.0 l6
a3 13.3 l8
a2 11.1 l2
a4 1.7 l1
答案2
您只需向 Perl 脚本添加一个测试即可。使用另一个散列,其键是第三个字段,并仅在该字段尚未出现时才打印每一行:
$ sort -nk2 file | perl -ane '$k{$F[$1]}=$_ unless $s{$F[2]}++>0;
END{print "$k{$_}" for keys(%k)}'
a3 2.5 l3
a2 2 l2
a1 2 l1
注意:这也会打印标题,但您的方法也会打印标题,并且由于您没有在输出中显示它,所以我假设标题实际上不是文件的一部分。