我已经 +1 了 karakfa 的回答。它简单而优雅。
我的答案是对 karakfa 的标头处理的扩展。如果你喜欢它,请随时 +1 我的答案,但“最佳答案”应该去 karakfa。 (当然,除非您更喜欢其他答案之一!:])
如果您的输入与您在问题中描述的一样,那么我们可以通过看到 $2 不是数字来识别标题。因此,以下内容不考虑标题:
$ sort -t, -k1,1 -k2,2nr filename | awk -F, '!a[$1]++'
您可以交替使用以下内容剥离标题:
$ sort -t, -k1,1 -k2,2nr filename | awk -F, '$2~/^[0-9]+$/&&!a[$1]++'
这会大大减慢速度,因为正则表达式的计算时间可能比简单的数组赋值和数值测试要长。我正在使用正则表达式进行数字测试,以允许 0,否则将评估为“假”。
接下来,如果您想保留标头,但先打印它,您可以在流的末尾处理您的输出:
$ sort -t, -k1,1 -k2,2nr filename | awk -F, '$2!~/^[0-9]+$/{print;next} !a[$1]++{b[$1]=$0} END{for(i in b){print b[i]}}'
在不将额外数组存储在内存中的情况下实现相同效果的最后一个选项是再次处理您的输入。这在 IO 方面成本更高,但在内存方面成本更低:
$ sort -t, -k1,1 -k2,2nr filename | awk -F, 'NR==FNR&&$2!~/^[0-9]+$/{print;nextfile} $2~/^[0-9]+$/&&!a[$1]++' filename -