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

Bash自定义排序:按ID分组,将指定行移至组首

按第一列分组并将匹配行移至组首的解决方案

这问题用awk处理最合适不过了,毕竟它天生擅长按字段分组和文本匹配。我给你写个脚本,完美贴合你的需求:

BEGIN { FS = "\t" }  # 请根据实际文件分隔符调整,空格分隔改为 FS="[[:space:]]+"
prev_id = ""
{
    # 提取第一列ID的最后一段(下划线分隔)作为匹配关键词
    n = split($1, id_parts, "_")
    match_key = id_parts[n]
    
    # 判断第二列是否包含这个匹配关键词
    if (index($2, match_key) > 0) {
        match_lines[$1] = match_lines[$1] $0 "\n"
    } else {
        non_match_lines[$1] = non_match_lines[$1] $0 "\n"
    }
    
    # 当分组切换时,输出前一组的内容(先匹配行,后不匹配行)
    if ($1 != prev_id && prev_id != "") {
        printf "%s%s", match_lines[prev_id], non_match_lines[prev_id]
        delete match_lines[prev_id]
        delete non_match_lines[prev_id]
    }
    prev_id = $1
}
END {
    # 处理最后一组数据
    printf "%s%s", match_lines[prev_id], non_match_lines[prev_id]
}

脚本工作原理

  • 字段分隔符设置:BEGIN块里的FS要根据你文件的实际分隔符调整——如果是制表符分隔就用"\t",如果是空格分隔就改成"[[:space:]]+"(匹配任意数量空格/制表符)。
  • 分组跟踪:用prev_id变量记录当前处理的第一列ID,实现按ID分组。
  • 匹配逻辑:拆分第一列ID,提取最后一个下划线后的片段(比如你的示例里aac(3)-IIa_1_X51534会提取出X51534),然后检查第二列是否包含这个片段。如果你的匹配规则不同,直接修改这里的判断逻辑就行——比如要判断第二列包含整个第一列,就改成index($2, $1) > 0。
  • 输出顺序:每个分组先输出所有匹配的行,再输出不匹配的行,保证匹配行在组首。

使用方法

  1. 把上面的脚本保存为reorder_lines.awk。
  2. 运行命令:awk -f reorder_lines.awk 你的输入文件名 > 输出文件名。

这个脚本利用awk的数组特性分组存储行,处理效率很高,哪怕你的文件很大也能轻松应对~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:31:31