在unix中根据密钥对所选记录进行排序
我的输入文件是这样的 01,A,34 01,A,35 01,A,36 01,A,37 02,A,40 02,A,41 02,A,42 02,A,45 01,A,34 01,A,35 01,A,36 01、A、37 02,A,40 02、A、41 02、A、42 02、A、45 我的输出需要 01,A,37 01,A,36 01,A,35 02,A,45 02,A,42 02,A,41 01、A、37 01,A,36 01,A,35 02、A、45 02、A、42 02、A、41 i、 e根据键(第一列和第二列),仅选择前三名记录(基于第三列的顶部值)在unix中根据密钥对所选记录进行排序,unix,shell,sorting,awk,Unix,Shell,Sorting,Awk,我的输入文件是这样的 01,A,34 01,A,35 01,A,36 01,A,37 02,A,40 02,A,41 02,A,42 02,A,45 01,A,34 01,A,35 01,A,36 01、A、37 02,A,40 02、A、41 02、A、42 02、A、45 我的输出需要 01,A,37 01,A,36 01,A,35 02,A,45 02,A,42 02,A,41 01、A、37 01,A,36 01,A,35 02、A、45 02、A、42 02、A、41 i、 e根据键(
提前感谢…如果数据如图所示,您可以使用一个简单的
bash
脚本来执行此操作
pax$ cat infile
01,A,34
01,A,35
01,A,36
01,A,37
02,A,40
02,A,41
02,A,42
02,A,45
pax$ ./go.sh
01,A,37
01,A,36
01,A,35
02,A,45
02,A,42
02,A,41
pax$ cat go.sh
keys=$(sed 's/,[^,]*$/,/' infile | sort -u)
for key in ${keys} ; do
grep "^${key}" infile | sort -r | head -3
done
第一行获取完整的键集,通过使用sed
删除最后一列,然后对输出进行排序,并使用sort
删除重复项,从前两个字段构造键集。在这种特殊情况下,键是01,A,
和02,A,
它提取每个键的相关数据(结合grep
的for
循环),使用sort-r
按降序排序,使用head
仅获取前三个键(每个键)
现在,如果您的密钥可能包含grep
的特殊字符,如
或[
,则需要注意。使用Perl:
perl-F,-lane'
推送{${join“,”,@F[0,1]},$F[2];
结束{
$k(钥匙%){
打印联接“,”,$k$_
对于(排序{$b$a}@{${$k})[0..2]
}
}“填充
hi pax…非常好…您的代码运行得非常好…但是当我将相同的逻辑应用于大量记录时,脚本挂起说没有内存…还有其他选择吗?@ain:sed的/,[^,]*$/,/infle | sort-u | while read key;do grep“^$key”infle | sort-r | head-3;done
。注意,对于大量记录,while
循环中的处理将是s..l..o..w!@aln,这取决于问题所在。文件中有多少行(使用wc-l infle
)?有多少唯一键(使用sed's/,[^,]*$/,/'inflee | sort-u | wc l
)“@pax:我有大约20万条记录,钥匙大约是10万个伟大的拉多洛夫…谢谢你…但我能在awk或sed中也得到同样的记录吗?你可以试试这样:sort-t,-k1,2-k3nr-infle | awk-F'.[$1,$2]+<3'
perl -F, -lane'
push @{$_{join ",", @F[0,1]}}, $F[2];
END {
for $k (keys %_) {
print join ",", $k, $_
for (sort { $b <=> $a } @{$_{$k}})[0..2]
}
}' infile