Awk 按长度高效拆分fastq文件

Awk 按长度高效拆分fastq文件,awk,fastq,Awk,Fastq,我试图找到一种按序列长度拆分fastq文件的省时方法,即将一个大的fastq文件拆分为多个只包含相同长度序列的文件。 输入是一个普通的fastq文件(每个序列4行,每个四重奏的第二行中有实际序列),具有不同的序列长度: @HISEQ:28:H8P69ADXX:1:1101:1462:2036 1:N:0:CTTGTA NCCATAAAGTAGAAAGCACT + #00<FFFFFFFFFIIFIIFF @HISEQ:28:H8P69ADXX:1:1101:1419:2156 1:N:0:

我试图找到一种按序列长度拆分fastq文件的省时方法,即将一个大的fastq文件拆分为多个只包含相同长度序列的文件。 输入是一个普通的fastq文件(每个序列4行,每个四重奏的第二行中有实际序列),具有不同的序列长度:

@HISEQ:28:H8P69ADXX:1:1101:1462:2036 1:N:0:CTTGTA
NCCATAAAGTAGAAAGCACT
+
#00<FFFFFFFFFIIFIIFF
@HISEQ:28:H8P69ADXX:1:1101:1419:2156 1:N:0:CTTGTA
TGGAGAGAAAGGCAGTTCCTGA
+
BBBFFFFFFFFFFIIIIIIIII
@HISEQ:28:H8P69ADXX:1:1101:1378:2223 1:N:0:CTTGTA
TCCTGTACTGAGCTGCCCCGA
+
BBBFFFFFFFFFFIIIIIIII
@HISEQ:28:H8P69ADXX:1:1101:1585:2081 1:N:0:CTTGTA
AAACCGTTACCATTACTGAGT
+
BBBFFFFFFFFFFIIIIFIII
如果我想为每个序列长度都有一个输出文件,我可以使用for循环进行管理:

for i in {16..33};
awk -v var=$i 'BEGIN {OFS = "\n"} {header = $0 ; getline seq ; getline qheader ; getline qseq ; if (length(seq) == var) {print header, seq, qheader, qseq}}'
done
问题是,尽管它工作得很好,但它相当耗时,因为我想我要分别检查每个长度的整个文件。此外,我需要事先检查最长和最短的序列

有人能帮我找到比我的循环更有效的解决方案吗?如果可能的话,我不需要指定一个范围,而是检查最小和最大长度并自动拆分它们的解决方案。我想在awk做这件事,但我对一切都持开放态度。 谢谢 Benedikt

像这样的东西

$ awk        '{rec=rec sep $0; sep=ORS} 
       !(NR%4){print rec > fn; rec=sep=""} 
       NR%4==2{fn = length($0)".seq"}' file
将生成包含内容的这3个文件

==> 20.seq <==
@HISEQ:28:H8P69ADXX:1:1101:1462:2036 1:N:0:CTTGTA
NCCATAAAGTAGAAAGCACT
+
#00<FFFFFFFFFIIFIIFF

==> 21.seq <==
@HISEQ:28:H8P69ADXX:1:1101:1378:2223 1:N:0:CTTGTA
TCCTGTACTGAGCTGCCCCGA
+
BBBFFFFFFFFFFIIIIIIII
@HISEQ:28:H8P69ADXX:1:1101:1585:2081 1:N:0:CTTGTA
AAACCGTTACCATTACTGAGT
+
BBBFFFFFFFFFFIIIIFIII

==> 22.seq <==
@HISEQ:28:H8P69ADXX:1:1101:1419:2156 1:N:0:CTTGTA
TGGAGAGAAAGGCAGTTCCTGA
+
BBBFFFFFFFFFFIIIIIIIII
像这样的事

$ awk        '{rec=rec sep $0; sep=ORS} 
       !(NR%4){print rec > fn; rec=sep=""} 
       NR%4==2{fn = length($0)".seq"}' file
将生成包含内容的这3个文件

==> 20.seq <==
@HISEQ:28:H8P69ADXX:1:1101:1462:2036 1:N:0:CTTGTA
NCCATAAAGTAGAAAGCACT
+
#00<FFFFFFFFFIIFIIFF

==> 21.seq <==
@HISEQ:28:H8P69ADXX:1:1101:1378:2223 1:N:0:CTTGTA
TCCTGTACTGAGCTGCCCCGA
+
BBBFFFFFFFFFFIIIIIIII
@HISEQ:28:H8P69ADXX:1:1101:1585:2081 1:N:0:CTTGTA
AAACCGTTACCATTACTGAGT
+
BBBFFFFFFFFFFIIIIFIII

==> 22.seq <==
@HISEQ:28:H8P69ADXX:1:1101:1419:2156 1:N:0:CTTGTA
TGGAGAGAAAGGCAGTTCCTGA
+
BBBFFFFFFFFFFIIIIIIIII

==>20.seq提醒我:不幸的是,我的问题有点不同。我想根据特定的标准(序列长度)分割我的fastq文件,而不仅仅是分割成一定数量的文件。如果按长度分割,最终会得到大小差异很大的文件,因为某些序列长度很少,而另一些序列长度非常丰富。但是谢谢你花时间!提醒我:不幸的是,我的问题有点不同。我想根据特定的标准(序列长度)分割我的fastq文件,而不仅仅是分割成一定数量的文件。如果按长度分割,最终会得到大小差异很大的文件,因为某些序列长度很少,而另一些序列长度非常丰富。但是谢谢你花时间!非常感谢,很抱歉我花了一段时间才回答。你的代码完全符合我的要求,与我的for循环相比,不到一半的时间。真正的5m3.676s用户3m25.148s sys 0m8.816s用于for循环,真正的2m2.489s用户0m32.216s sys 0m1.876s用于您的循环。另一方面,您能解释一下您的代码吗?我想更好地理解awk。我可以看到为了得到不同的输出文件名我必须改变什么,但除此之外,我很迷茫。再次感谢你的解释,我想我现在明白你在那里做了什么。没问题,请向前支付!我试图将您的脚本从fastq文件改编为fasta文件(基本上是相同的文件类型,但每个序列只有2行,而不是4行)。我将每次出现的NR%4都更改为NR%2,认为这是一个简单的修复方法,但我得到了以下错误:致命错误:“>”重定向的表达式具有空字符串值。其他一切都一样。非常感谢您的帮助。非常感谢,很抱歉我花了一段时间才回答。你的代码完全符合我的要求,与我的for循环相比,不到一半的时间。真正的5m3.676s用户3m25.148s sys 0m8.816s用于for循环,真正的2m2.489s用户0m32.216s sys 0m1.876s用于您的循环。另一方面,您能解释一下您的代码吗?我想更好地理解awk。我可以看到为了得到不同的输出文件名我必须改变什么,但除此之外,我很迷茫。再次感谢你的解释,我想我现在明白你在那里做了什么。没问题,请向前支付!我试图将您的脚本从fastq文件改编为fasta文件(基本上是相同的文件类型,但每个序列只有2行,而不是4行)。我将每次出现的NR%4都更改为NR%2,认为这是一个简单的修复方法,但我得到了以下错误:致命错误:“>”重定向的表达式具有空字符串值。其他一切都一样。非常感谢您的帮助。