如何在UNIX环境下统计制表符文件第二列不同子串的出现次数?
解决UNIX下制表符文件特定字段值的计数问题
看起来你可能描述时有点小偏差——从你的输入和期望输出来看,你实际是想统计每行**从第4个字段开始的所有基因型值(比如AA、AC)**的出现次数,再把统计结果追加到行尾对吧?下面给你一个用awk实现的完美方案,这是UNIX环境处理这类文本任务的首选工具。
核心解决方案:awk脚本实现
你可以直接运行这条命令,或者把它保存成脚本文件复用:
awk ' BEGIN { FS = "\t" # 设置输入分隔符为制表符 OFS = "\t" # 设置输出分隔符为制表符,保证原格式不变 } { # 清空计数数组,避免上一行数据干扰当前行统计 delete count # 遍历第4到最后一个字段,统计每个值的出现次数 for (i = 4; i <= NF; i++) { count[$i]++ } # 构建统计结果字符串,格式为「值=次数;值=次数」 stats = "" for (val in count) { if (stats != "") { stats = stats ";" } stats = stats val "=" count[val] } # 输出原行内容 + 统计结果 print $0, stats } ' 你的输入文件名 > 输出文件名
命令细节解释
- BEGIN块:在处理任何行之前执行,统一设置输入输出的制表符分隔,确保文件原有格式不被破坏。
- 计数逻辑:用
count数组记录每个基因型值的出现次数,只遍历第4到末尾的字段(因为前三个是rsID、基因型标记、染色体号)。 - 统计字符串构建:遍历
count数组的键值对,拼接成你需要的AA=9;AC=2格式。 - 输出:将原行内容与统计结果用制表符分隔后输出,重定向到指定的输出文件。
示例验证
用你给出的输入示例:
rs12255619 A/C chr10 AA AA AC AA AA AA AA AA AA AC AA
rs7909677 A/G chr10 AA AA AA AA AA AA AA AA AA AA AA
运行命令后,输出会是:
rs12255619 A/C chr10 AA AA AC AA AA AA AA AA AA AC AA AA=9;AC=2
rs7909677 A/G chr10 AA AA AA AA AA AA AA AA AA AA AA AA=11
如果我理解错了,你确实是要统计第二列(比如A/C)中的子串出现次数,可以用这个修改版脚本,拆分第二列的/分隔符来统计:
awk ' BEGIN { FS = "\t" OFS = "\t" } { delete count # 拆分第二列的子串,按/分隔 split($2, subs, "/") for (i in subs) { count[subs[i]]++ } stats = "" for (val in count) { if (stats != "") stats = stats ";" stats = stats val "=" count[val] } print $0, stats } ' 你的输入文件名 > 输出文件名
这个版本会给第一行追加A=1;C=1,第二行追加A=1;G=1,你可以根据实际需求选择。
内容的提问来源于stack exchange,提问作者Perceval Vellosillo Gonzalez
相关产品推荐
相关产品推荐

