2014-05-21 69 views
0

我已經花了太多的時間在這,我期待的建議。我有非常大的文件(對於那些感興趣的人來說,Illumina測序運行的FASTQ文件)。我需要做的是不匹配的重複(存在於原始文件),該行的文件和打印,加上3個系在其下方爲兩個單獨的文件之間的共同模式。 Grep這樣做很好,但是文件大約18GB,並且它們之間的匹配速度很慢。我需要做的例子如下。grep的模式匹配的方法太慢

FILEA:

@DLZ38V1_0262:8:1101:1430:2087#ATAGCG/1 
NTTTCAGTTAGGGCGTTTGAAAACAGGCACTCCGGCTAGGCTGGTCAAGG 
+DLZ38V1_0262:8:1101:1430:2087#ATAGCG/1 
BP\cccc^ea^eghffggfhh`bdebgfbffbfae[_ffd_ea[H\_f_c 
@DLZ38V1_0262:8:1101:1369:2106#ATAGCG/1 
NAGGATTTAAAGCGGCATCTTCGAGATGAAATCAATTTGATGTGATGAGC 
+DLZ38V1_0262:8:1101:1369:2106#ATAGCG/1 
BP\ccceeggggfiihihhiiiihiiiiiiiiihighiighhiifhhhic 
@DLZ38V1_0262:8:2316:21261:100790#ATAGCG/1 
TGTTCAAAGCAGGCGTATTGCTCGAATATATTAGCATGGAATAATAGAAT 
+DLZ38V1_0262:8:2316:21261:100790#ATAGCG/1 
__\^c^ac]ZeaWdPb_e`KbagdefbZb[cebSZIY^cRaacea^[a`c 

你可以看到3個唯一的標題開始@其次是3條額外的線路

FILEB:

@DLZ38V1_0262:8:1101:1430:2087#ATAGCG/2 
GAAATCAATGGATTCCTTGGCCAGCCTAGCCGGAGTGCCTGTTTTCAAAC 
+DLZ38V1_0262:8:1101:1430:2087#ATAGCG/2 
_[_ceeeefffgfdYdffed]e`gdghfhiiihdgcghigffgfdceffh 
@DLZ38V1_0262:8:1101:1369:2106#ATAGCG/2 
GCCATTCAGTCCGAATTGAGTACAGTGGGACGATGTTTCAAAGGTCTGGC 
+DLZ38V1_0262:8:1101:1369:2106#ATAGCG/2 
_aaeeeeegggggiiiiihihiiiihgiigfggiighihhihiighhiii 
@DLZ38V1_0262:8:1101:1369:2106#ATAGCG/2 
GCCATTCAGTCCGAATTGAGTACAGTGGGACGATGTTTCAAAGGTCTGGC 
+DLZ38V1_0262:8:1101:1369:2106#ATAGCG/2 
_aaeeeeegggggiiiiihihiiiihgiigfggiighihhihiighhiii 
@DLZ38V1_0262:8:1101:1369:2106#ATAGCG/2 
GCCATTCAGTCCGAATTGAGTACAGTGGGACGATGTTTCAAAGGTCTGGC 
+DLZ38V1_0262:8:1101:1369:2106#ATAGCG/2 
_aaeeeeegggggiiiiihihiiiihgiigfggiighihhihiighhiii 

有4頭這裏但只有2作爲其中的一個重複3次

我需要它們下面的3條線的兩個文件之間的共同頭,不重複加是唯一的。在每個文件中以相同的順序。

這是我到目前爲止有:

grep -E @DLZ38V1.*/ --only-matching FileA | sort -u -o FileA.sorted 
grep -E @DLZ38V1.*/ --only-matching FileB | sort -u -o FileB.sorted 
comm -12 FileA.sorted FileB.sorted > combined 

結合

@DLZ38V1_0262:8:1101:1369:2106#ATAGCG/ 
@DLZ38V1_0262:8:1101:1430:2087#ATAGCG/ 

這僅僅是兩個文件之間的共同頭,不重複。這就是我要的。 現在我需要匹配這些標題的原始文件,抓住3線下方,但他們只有一次。

如果我使用grep我能得到我想要的東西每個文件

while read -r line; do 
    grep -A3 -m1 -F $line FileA 
done <combined> FileA.Final 

FileA.Final

@DLZ38V1_0262:8:1101:1369:2106#ATAGCG/1 
NAGGATTTAAAGCGGCATCTTCGAGATGAAATCAATTTGATGTGATGAGC 
+DLZ38V1_0262:8:1101:1369:2106#ATAGCG/1 
BP\ccceeggggfiihihhiiiihiiiiiiiiihighiighhiifhhhic 
@DLZ38V1_0262:8:1101:1430:2087#ATAGCG/1 
NTTTCAGTTAGGGCGTTTGAAAACAGGCACTCCGGCTAGGCTGGTCAAGG 
+DLZ38V1_0262:8:1101:1430:2087#ATAGCG/1 
BP\cccc^ea^eghffggfhh`bdebgfbffbfae[_ffd_ea[H\_f_c 

while循環重複產生FileB.Final

@DLZ38V1_0262:8:1101:1369:2106#ATAGCG/2 
GCCATTCAGTCCGAATTGAGTACAGTGGGACGATGTTTCAAAGGTCTGGC 
+DLZ38V1_0262:8:1101:1369:2106#ATAGCG/2 
_aaeeeeegggggiiiiihihiiiihgiigfggiighihhihiighhiii 
@DLZ38V1_0262:8:1101:1430:2087#ATAGCG/2 
GAAATCAATGGATTCCTTGGCCAGCCTAGCCGGAGTGCCTGTTTTCAAAC 
+DLZ38V1_0262:8:1101:1430:2087#ATAGCG/2 

這作品,但FileA和FileB是〜18GB,我的組合文件大約是〜2GB。有沒有人有任何建議,我可以大大加快最後一步?

+0

不是每個頭都做一個'grep',每次都重新掃描整個文件,爲什麼不把所有的頭文件放在一個文件中,並執行'grep -A3 -m1 -F -f header_list.txt FileA'? – twalberg

+0

是的,問題在於-m1在首次擊中後被殺死。 – user3272284

回答

1

想到我應該發佈修復我想出了這個。一旦我獲得了組合文件(上圖),我使用了perl哈希引用將它們讀入內存並掃描文件A.文件A中的匹配被散列並用於掃描文件B.這仍然佔用大量內存,但工作速度非常快。從grep 20+天到20分鐘。

1

取決於你需要如何經常做運行此:

  1. 你可以轉儲(你可能會想以後建索引的批量插入),您的數據轉換成一個Postgres(?sqlite的)數據庫,建立一個索引,並享受40年的研究成果,實現關係數據庫的高效實現,幾乎不需要您的投資。

  2. 你可以通過使用unix實用程序'join'來模仿關係型數據庫,但不會有太多的喜悅,因爲這不會給你一個索引,但它可能比'grep ',你可能會遇到物理限制......我從來沒有嘗試加入兩個18G文件。你可以編寫一些C代碼(把你最喜歡的編譯過的代碼轉換成機器代碼),它將你的字符串(只有四個字母,對嗎?)轉換成二進制文件,並建立一個索引(或更多)在上面。由於你的五十個字符串只會佔用兩個64位字,所以可以使閃電速度快和佔用內存小。