grep每四行输入一次.fastq

grep每四行输入一次.fastq,grep,fastq,Grep,Fastq,我正在使用bash在linux机器上工作 我的问题是,如何使用grep跳过查询文件中的行 我正在使用一个名为example.fastq的大~16Gb.fastq文件,该文件的格式如下 example.fastq @SRR6750041.1 1/1 CTGGANAAGTGAAATAATATAAATTTTTCCACTATTGAATAAAAGCAACTTAAATTTTCTAAGTCG + AAAAA#EEEEEEEEEEEEEEEEEEEEEEEAEEEEEEEEEEEEEEEEEEEEEEEEEA&

我正在使用bash在linux机器上工作

我的问题是,如何使用grep跳过查询文件中的行

我正在使用一个名为
example.fastq
的大~16Gb.fastq文件,该文件的格式如下

example.fastq

@SRR6750041.1 1/1
CTGGANAAGTGAAATAATATAAATTTTTCCACTATTGAATAAAAGCAACTTAAATTTTCTAAGTCG
+
AAAAA#EEEEEEEEEEEEEEEEEEEEEEEAEEEEEEEEEEEEEEEEEEEEEEEEEA<AAEEEEE<6
@SRR6750041.2 2/1
CTATANTATTCTATATTTATTCTAGATAAAAGCATTCTATATTTAGCATATGTCTAGCAAAAAAAA
+
AAAAA#EE6EEEEEEEEEEEEAAEEAEEEEEEEEEEEE/EAE/EAE/EA/EAEAAAE//EEAEAA6
@SRR6750041.3 3/1
ATCCANAATGATGTGTTGCTCTGGAGGTACAGAGATAACGTCAGCTGGAATAGTTTCCCCTCACAG
+
AAAAA#EE6E6EEEEEE6EEEEAEEEEEEEEEEE//EAEEEEEAAEAEEEAE/EAEEA6/EEA<E/
@SRR6750041.4 4/1
ACACCNAATGCTCTGGCCTCTCAAGCACGTGGATTATGCCAGAGAGGCCAGAGCATTCTTCGTACA
+
/AAAA#EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAE/E/<//AEA/EA//E//
@SRR6750041.5 5/1
CAGCANTTCTCGCTCACCAACTCCAAAGCAAAAGAAGAAGAAAAAGAAGAAAGATAGAGTACGCAG
+
AAAAA#EEEEEEEEEEEEEAEEEEEEEEEEEEEEEEEEEEEEEEEEEEE/EEEAEEEAEEE<EE/E
这将正确地输出以下内容

@SRR6750041.2 2/1
CTATANTATTCTATATTTATTCTAGATAAAAGCATTCTATATTTAGCATATGTCTAGCAAAAAAAA
+
AAAAA#EE6EEEEEEEEEEEEAAEEAEEEEEEEEEEEE/EAE/EAE/EA/EAEAAAE//EEAEAA6
@SRR6750041.5 5/1
CAGCANTTCTCGCTCACCAACTCCAAAGCAAAAGAAGAAGAAAAAGAAGAAAGATAGAGTACGCAG
+
AAAAA#EEEEEEEEEEEEEAEEEEEEEEEEEEEEEEEEEEEEEEEEEEE/EEEAEEEAEEE<EE/E
@SRR6750041.2 2/1
ctatattctatattctataaaaagcattctatattatagcatatgtagcaaaaaaaaa
+
AAAAA#ee6eeeeeeeeeeeeeee/EAE/EAE/EA/eaeaeaaae//eeaeaaa6
@SRR6750041.5 5/1
CAGCANTCTCGCTCACAACTCCAAGCAAGAGAGAGAGAGAGAGTACGCAG
+

AAAAA#eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee。出于测试目的,我创建了一个测试用例作为您的示例的迷你版,示例_mini.fastq的大小为145 MB,而IDarray有999个元素(兴趣)

您的版本具有此性能(用户空间超过2分钟):

在第一次匹配
-m1
后,第一次升级grep以结束grep,我假设兴趣ID是唯一的。这将减少50%的复杂性,并占用用户空间约1分钟:

$ time for i in "${arr[@]}"; do grep -A 3 "${i}" example_mini.fastq; done 1> out.txt
real    3m16.310s
user    2m9.645s
sys     0m53.092s

$ md5sum out.txt
8f199a78465f561fff3cbe98ab792262  out.txt
$ time for i in "${arr[@]}"; do grep -m 1 -A 3 "${i}" example_mini.fastq; done 1> out.txt
real    1m19.325s
user    0m55.844s
sys     0m21.260s

$ md5sum out.txt
8f199a78465f561fff3cbe98ab792262  out.txt
这些解与元素的数量成线性关系。在大文件上调用n次grep

现在让我们只在AWK中实现一次运行,我将IDarray导出到输入文件中,以便在一次运行中进行处理。我将大文件加载到每个ID的关联数组中,然后在ID数组中循环1x进行搜索。这是一个通用场景,您可以定义regexp和打印后的行数。这很复杂,只有一次运行文件+N比较。这是2000%的加速:

$ for i in "${arr[@]}"; do echo $i; done > IDarray.txt
$ time awk '
(FNR==NR) && (linesafter-- > 0) { arr[interest]=arr[interest] RS $0; next; }
(FNR==NR) && /^@/ { interest=$1; arr[interest]=$0; linesafter=3; next; }
(FNR!=NR) && arr[$1] { print(arr[$1]); }
' example_mini.fastq IDarray.txt 1> out.txt
real    0m7.044s
user    0m6.628s
sys     0m0.307s

$ md5sum out.txt
8f199a78465f561fff3cbe98ab792262  out.txt
就像你的标题一样,如果你真的能确认每四行是感兴趣的id,三行之后就要打印了。你可以简化成这样,再加速20%:

$ for i in "${arr[@]}"; do echo $i; done > IDarray.txt
$ time awk '
(FNR==NR) && (FNR%4==1) { interest=$1; arr[interest]=$0; next; }
(FNR==NR) { arr[interest]=arr[interest] RS $0; next; }
(FNR!=NR) && arr[$1] { print(arr[$1]); }
' example_mini.fastq IDarray.txt 1> out.txt
real    0m5.944s
user    0m5.593s
sys     0m0.242s

$ md5sum out.txt
8f199a78465f561fff3cbe98ab792262  out.txt
在包含999个元素的1.5 GB文件上,搜索时间为:

real    1m4.333s
user    0m59.491s
sys     0m3.460s

因此,根据我在我的机器上的预测,您的15 GB示例(包含10k元素)在用户空间中处理大约需要16分钟。

每行的字符数是否相同?即使使用
awk'NR%4==0'
我猜它仍将读取整个文件,因此I/O将是相同的。这
或跳过第2,3,4和6,7,8行等
似乎不清楚。你能详细说明一下吗?匹配
@SRR6750041.1
不可能包含在example.fastq的第2、3、4或6、7、8行中。因此,使用grep搜索它们是徒劳的。这有意义吗?只有找到匹配项后,这些行才有意义。搜索精确模式的问题是什么?(
grep
足够快)@RomanPerekhrest问得好!我想它也足够快了。。。但是,对于一个~16Gb的输入文件和10046个大小在1kb到100Mb之间的字符串列表,在linux集群的56个内核上并行运行这种大小的运行需要几天的时间。下面是到github存储库的链接,其中包含完整的脚本和一个小示例数据集。我非常重视你对如何加快这一进程的任何见解。
real    1m4.333s
user    0m59.491s
sys     0m3.460s