You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Bash脚本筛选保留相同序列编号的最大数值行?

问题:保留每个序列编号对应数值最大的行

给定如下输入数据:

# Sequence                 6 S   TTHTSTAQR   0.687
# Sequence                 7 T   THTSTAQRS   0.562
# Sequence                11 S   TAQRSSKYP   0.960
# Sequence                11 S   TAQRSSKYP   0.711
# Sequence                12 S   AQRSSKYPT   0.996
# Sequence                12 S   AQRSSKYPT   0.684

期望输出为每个序列编号(第三列)保留数值(第五列)最大的行:

# Sequence                 6 S   TTHTSTAQR   0.687
# Sequence                 7 T   THTSTAQRS   0.562
# Sequence                11 S   TAQRSSKYP   0.960
# Sequence                12 S   AQRSSKYPT   0.996

尝试使用awk -F, '!seen[$3]++' tmp > out无法完成需求,该如何解决?


问题分析

你原来的命令有两个核心问题:

  1. 指定了-F,用逗号作为分隔符,但你的数据是空格分隔的,导致$3无法正确获取序列编号;
  2. !seen[$3]++的逻辑是保留每个键第一次出现的行,而不是数值最大的行,不符合需求。

正确的AWK命令

基础版(输出顺序不保证和原文件一致)

awk '{
    key = $3
    val = $5 + 0  # 转为数字类型,避免字符串比较误差
    if (!(key in max_val) || val > max_val[key]) {
        max_val[key] = val
        line[key] = $0
    }
} END {
    for (k in line) print line[k]
}' tmp > out

保持原顺序版(和示例输出顺序一致)

如果需要保持序列编号在原文件中第一次出现的顺序,用以下命令:

awk '{
    key = $3
    val = $5 + 0
    if (!(key in max_val)) {
        order[++cnt] = key  # 记录首次出现的顺序
    }
    if (val > max_val[key] || !(key in max_val)) {
        max_val[key] = val
        line[key] = $0
    }
} END {
    for (i=1; i<=cnt; i++) print line[order[i]]
}' tmp > out

命令解释

  • key = $3:以第三列的序列编号作为唯一标识;
  • val = $5 + 0:将第五列的字符串数值转为数字,确保比较时是数值大小而非字符串字典序;
  • 条件判断:如果当前序列编号未记录过,或者当前行的数值大于已记录的最大值,就更新最大值和对应的整行内容;
  • END块:遍历存储的结果,输出最终保留的行(保持顺序版会按原文件中序列首次出现的顺序输出)。

内容的提问来源于stack exchange,提问作者Akash Mondal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:12:26