我有一个带入藏号的文件。这些数字需要根据ID映射到另一个文件中,并使用该信息和补充的mysql数据库信息写入第三个文件。我有一个简单的程序,它读取文件(145Gb),提取入藏号,然后使用grep命令在映射文件(10Gb)中找到相应的ID。 因此,对于每个入藏号我正在执行一个grep:
$ grep -m1 myAccession myMappFile
此操作已执行多次。当我一遍又一遍地访问同一个文件时,我想知道是否有一种简单的方法来创建一个索引或某种bash魔法,它可以提高性能,因为我要处理大约45,000,000的种质。 我在~3h加工了250k种。因此处理45M将需要约540小时(22天!!),这是不负担得起的...... 我知道我可以改进一次发送一个包含多个种质的grep:
$ grep 'accession1\|accession2\|accession3' -m3 myMappFile
但这还不够。
可能是这样的:
$ grep 'accession1\|accession2\|accession3' -m3 myIndexedMappFile
注意:数据库进程已经改进,我通过使用hashmap大大减少了数据库访问,因此肯定的瓶颈位于grep上。
有什么想法吗?
更新
*File with accession:*
>Accession_A other text
other line
...
...
>Accession_B more text
more lines
...
*File with mappings*
Col1 Accession_A ID-X Col4
Col1 Accession_B ID-Y Col4
...
...
所以程序读取Accession文件(逐行)提取Accession_N,然后grep为映射文件上的加入。使用结果行,我提取ID值并使用该ID搜索更多数据到数据库中,所以最后我有一个文件:
Accession_A ID-X DB-DATA
Accession_B ID-Y DB-DATA
没有文件排序。我将值{ID,DB-DATA}放入哈希映射中以避免数据库开销。
该程序使用java编写一个使用进程来执行grep命令,以减少Runtime.exec调用的开销我尝试一次运行多个访问的grep,但它几乎相同...
答案 0 :(得分:0)
我已经解决了@sundeep的建议,并在处理时间方面找到了解决方案,但我认为当用户需要执行多个时,我仍然应该更好地改进用例greps在同一个文件上。 我做的是:
首先从第一个文件中提取所有入藏号:
grep -e "^>" myBigFile.fa | cut -d">" -f2 | cut -d" " -f1 > all_accession.txt
然后使用带文件引用的grep
grep -F -f all_accession.txt myBigMappingFile > matchFile.txt
最后使用java程序处理matchFile.txt以读取ID并创建目标文件(使用进程我的意思是只读取ID并查看数据库中的补充信息)。
这三个步骤在3.5小时内完成,这是更可接受的。 但是解决方案并不完整,因为一起运行(因为我从一开始就一直在尝试)也会生成其他输出文件,最重要的是,一个文件的加入对象上没有相应的ID映射文件,因此我尝试使用以下命令生成该文件:
grep -F -v -f all_accession.txt myBigMappingFile > matchFile.txt
使用-v param grep以反转选择,但该命令还提供myBigMappingFile上的记录,该记录在all_accession.txt文件中找不到匹配的文件,这不是所需的输出....