Bash:根据未在索引列表中的索引提取文件行
用awk快速筛选不在指定索引列表的测序条目
嘿,这个需求用awk就能高效解决,我平时处理fastq格式的测序数据经常这么干,给你详细说下怎么做:
核心思路
首先我们要把File A里的排除索引存成一个可快速查询的集合,然后按4行一组(标准fastq的每条read结构)遍历File B,只要组内ID行的索引不在排除列表里,就把整个组输出。
完整命令
直接用这条命令就行,把FileA.txt和FileB.fastq换成你的实际文件名,结果会存到filtered_file.fastq里:
awk 'NR==FNR {exclude[$1]; next} {block[++i]=$0} i==4 {split(block[1], id, " "); if (!(id[2] in exclude)) {print block[1]; print block[2]; print block[3]; print block[4]}; i=0}' FileA.txt FileB.fastq > filtered_file.fastq
逐行解释命令
NR==FNR {exclude[$1]; next}:先处理第一个文件(File A),把每个索引都放进exclude数组里,这样后面判断的时候能快速查询。{block[++i]=$0}:处理File B时,把每一行暂存到block数组里,i用来计数当前是组内第几条行。i==4:当攒够4行(也就是一条完整的测序read)时,开始做判断:split(block[1], id, " "):把@开头的ID行按空格切开,第二个字段就是我们要找的索引(比如你示例里的5、8)。if (!(id[2] in exclude)):如果这个索引不在排除列表里,就把这4行全打印出来。i=0:重置计数器,准备处理下一条read。
验证你的示例场景
你给的示例里,索引5和8都不在File A的排除列表(1、2、3、4、13、14、15、16、19、20)里,所以这两个完整的read都会被保留到输出文件里,完全符合你的需求。
小提醒
如果你的File A是每行一个索引(而不是空格分隔),这个命令也能用,因为awk会逐行读取每个索引存入数组。要是你的File B不是标准4行一条的fastq格式,那可能得调整下分组的行数,但大部分测序数据都是标准格式,这个命令应该直接能用。
内容的提问来源于stack exchange,提问作者Maria
相关产品推荐
相关产品推荐

