我试图找到一种耗时较少的方法来按顺序长度分割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
现在我使用awk过滤掉特定长度或特定范围内的序列:
awk 'BEGIN {OFS = "\n"} {header = $0 ; getline seq ; getline qheader ; getline qseq ; if (length(seq) == 22) {print header, seq, qheader, qseq}}'
如果我想为每个序列长度都有一个输出文件,我使用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中这样做,但我会为所有事情敞开心扉。 谢谢 本尼迪克特
答案 0 :(得分:3)
这样的事情?
$ 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
因为会有少数这些输出文件,所以不需要显式关闭它们。
<强>解释强>
如果行号是4的倍数,则
{rec=rec sep $0; sep=ORS}
在行之间逐行构建记录行,使用分隔符的延迟初始化,我们可以消除悬空的第一个分隔符。
!(NR%4)
{print rec > fn; rec=sep=""}
将记录打印到文件并重置记录和分隔符
NR%4==2
如果行号是2的4。
{fn = length($0)".seq"}
设置文件名