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

如何使用Bash按条件过滤FASTQ格式文件中的行?

嘿,我来帮你搞定FASTQ文件的Bash过滤问题~

首先得记住:FASTQ是四行一组存储测序reads的格式,每组对应一个read——第1行是@开头的标识符,第2行是测序序列,第3行是+开头的分隔行,第4行是对应序列的质量值。过滤时一定要完整保留符合条件的整个read,不能只挑单行处理,不然文件结构就乱了。

下面是几种常见过滤场景的具体实现,用Bash里最常用的awk工具(效率高,处理大文件也没问题):

1. 保留序列长度达标的reads

比如想留下序列长度≥50的reads:

awk 'BEGIN{OFS="\n"} {r[NR%4]=$0} NR%4==0 {if(length(r[2])>=50) print r[1],r[2],r[3],r[4]}' input.fastq > filtered.fastq

逻辑很简单:用数组r缓存每组的4行,当处理完一组(NR%4==0)时,检查第2行(序列行)的长度,符合要求就输出整个read的4行。

2. 去掉序列里含N的reads

如果你的数据里有不确定的碱基(N),想过滤掉这些reads:

awk 'BEGIN{OFS="\n"} {r[NR%4]=$0} NR%4==0 {if(r[2] !~ /N/) print r[1],r[2],r[3],r[4]}' input.fastq > filtered.fastq

这里用正则匹配r[2](序列行),如果不含N就输出整组。

3. 根据质量值过滤(比如平均质量≥20)

假设你的质量值是最常用的Phred+33编码(ASCII码减33得到实际质量值),计算平均质量后过滤:

awk '
BEGIN{OFS="\n"}
{ r[NR%4] = $0 }
NR%4 == 0 {
    sum = 0
    len = length(r[4])
    for(i=1; i<=len; i++) {
        sum += ord(substr(r[4], i, 1)) - 33
    }
    avg = sum / len
    if(avg >= 20) print r[1], r[2], r[3], r[4]
}
function ord(c) { return sprintf("%d", c) }
' input.fastq > filtered.fastq

这段脚本会遍历质量行的每个字符,转成实际质量值后算平均值,达标就输出整个read。

4. 按标识符过滤(比如保留特定ID的reads)

如果想根据第1行的标识符筛选,比如保留ID里包含199563512的reads:

awk 'BEGIN{OFS="\n"} {r[NR%4]=$0} NR%4==0 {if(r[1] ~ /199563512/) print r[1],r[2],r[3],r[4]}' input.fastq > filtered.fastq

用正则匹配标识符行(r[1])里的目标字符串就行。

小提示

  • 要是需要组合多个条件,比如同时保留长度≥50且不含N的reads,直接把条件用&&连起来:
awk 'BEGIN{OFS="\n"} {r[NR%4]=$0} NR%4==0 {if(length(r[2])>=50 && r[2]!~/N/) print r[1],r[2],r[3],r[4]}' input.fastq > filtered.fastq
  • 确保你的FASTQ是严格四行一组的,没有缺失或多余的行,不然脚本可能出问题
  • 大文件优先用awk,比纯Bash循环或者sed高效得多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:59:44