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

基于pos列去除.tsv重复行并保留指定列数据(bash/perl)

用AWK高效处理TSV文件的去重与列合并需求

嘿,你的需求用AWK就能完美搞定,而且比先排序再逐行对比的思路更简洁高效!毕竟AWK天生就是为这类文本数据处理而生的,直接用它的关联数组(哈希表)就能按pos列去重,同时合并指定列的数据。

直接可用的命令脚本

针对你的需求,我写了一个AWK脚本,能同时处理多个.tsv文件,还会自动解决多文件的表头重复问题:

awk 'BEGIN{FS=OFS="\t"; header_printed=0} 
NR==1{
    # 只打印一次表头,避免多文件重复输出
    if (!header_printed) {
        print; 
        header_printed=1
    }
    next
} 
{
    # 用pos作为唯一标识存储数据
    if (!($2 in pos_map)) {
        pos_map[$2]["rownbr"] = $1
        pos_map[$2]["percentage"] = $4
        pos_map[$2]["pvalue"] = $3
        pos_map[$2]["samplename"] = $5
    } else {
        # 遇到重复pos时,追加pvalue和samplename的值
        pos_map[$2]["pvalue"] = pos_map[$2]["pvalue"] "," $3
        pos_map[$2]["samplename"] = pos_map[$2]["samplename"] "," $5
    }
}
END{
    # 遍历所有存储的pos数据,按要求格式输出
    for (pos in pos_map) {
        print pos_map[pos]["rownbr"], pos, pos_map[pos]["pvalue"], pos_map[pos]["percentage"], pos_map[pos]["samplename"]
    }
}' *.tsv | sort -k2,2

脚本细节拆解

  1. BEGIN块:设置输入输出分隔符为制表符(\t),确保TSV格式不混乱;初始化header_printed标记,避免多文件的表头重复打印。
  2. 表头处理:仅在第一个文件的第一行打印表头,后续文件的表头直接跳过。
  3. 核心去重合并逻辑:
    • 以$2(pos列)作为关联数组pos_map的键,第一次遇到某个pos时,存储该行的rownbr、percentage、pvalue和samplename。
    • 再次遇到相同pos时,只追加pvalue和samplename的内容,用逗号分隔。
  4. END块:遍历所有存储的pos数据,按你需要的列顺序输出,最后通过sort -k2,2保证结果按pos列排序,和你最初的思路匹配。

效果验证

用你提供的示例数据测试,运行命令后会输出完全符合预期的结果:

rownbr pos pvalue percentage samplename
1 chr1_12000 0.05 5.6 S1
1 chr1_12500 0.04,0.03 15.9 S1,S3
3 chr1_12570 0.9 45.3 S2

这个脚本处理大型TSV文件也很高效,因为AWK的关联数组查找是O(1)复杂度,比先排序再逐行对比的方法性能更优。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 23:57:31