根據第一列合併多個檔案並節省記憶體問題

根據第一列合併多個檔案並節省記憶體問題

我有多個製表符分隔的 fastq 檔案。我想匹配每次讀取的第二行,如果匹配則將其旁邊的值相加。例如:


file1.fq
>1
ATGCCGTT      file1:1
+
HHHHKKKK

file2.fq
>2
ATGCCGTT       file2:3
+
JJKHHTTT

>3
ATTCCAAC        file2:1
+
=#GJLMNB

我想要的輸出是這樣的:


output.txt

ATGCCGTT      file1:1    file2:3     count:4
ATTCCAAC      file2:1          count:1

我寫的程式碼是:



#!/usr/bin/env perl
use strict;
use warnings;
no warnings qw( numeric );
my %seen;


$/ = "";
while () {
    chomp;
    my ($key, $value) = split ('\t', $_);

    my @lines = split /\n/, $key;
    my $key1 = $lines[1];

    $seen{$key1} //= [ $key ];
    push (@{$seen{$key1}}, $value);

}

foreach my $key1 ( sort keys %seen ) {
my $tot = 0;
my $file_count = @ARGV;
for my $val ( @{$seen{$key1}} ) {
        $tot += ( split /:/, $val )[0];
    }   

if ( @{ $seen{$key1} } >= $file_count) {


        print join( "\t", @{$seen{$key1}});
        print "\tcount:". $tot."\n\n";
    }
}

該程式碼適用於小文件,但當我想比較大文件時,它會佔用整個內存,導致腳本運行而沒有結果。我想修改腳本,使其不佔用記憶體。我不想使用任何模組。我認為如果我一次只加載一個文件到內存中,它會節省內存,但無法做到這一點。請幫忙修改我的腳本。

答案1

你有沒有嘗試過awk?不確定它能更好地處理大文件perl,但可能值得一試:

在你的 awk 腳本中:

BEGIN {
    RS=">[0-9]+"
}

FNR==1{next}

NR==FNR {
    a[$1]++
    next
}


$1 in a {
    b[$1]++
    next
}

{
    c[$1]++
}

END {
    for (key in a) {
        if (b[key] == "") {
            printf key"\tfile1:"a[key]"\t\tcount:"a[key]"\n"
        } else {
            printf key"\tfile1:"a[key]"\tfile2:"b[key]"\tcount:"a[key]+b[key]"\n"
        }
    }
    for (key in c) {
        printf key"\t\tfile2:"c[key]"\tcount:"c[key]"\n"
    }
}

運行它:

$ awk -f myscript.awk file1 file2 > output.txt

測試它:

文件1

>1
ATGCCGTT      file1:1
+
HHHHKKKK

>2
ATTCCAACg        file2:1
+
=#GJLMNB

文件2

>2
ATGCCGTT       file2:3
+
JJKHHTTT

>3
ATTCCAAC        file2:1
+
=#GJLMNB

終端輸出:

ATTCCAACg   file1:1         count:1
ATGCCGTT    file1:1 file2:1 count:2
ATTCCAAC            file2:1 count:1

答案2

將這些神秘咒語添加到您的程式中

use DB_File;
my %seen; 
unlink '/tmp/translation.db';
sleep 2; 
tie ( %seen, 'DB_File', '/tmp/translation.db' )
    or die "Can't open /tmp/translation.db\n";

並且您的哈希將不再駐留在記憶體中,而是駐留在磁碟上的資料庫中。您可以將其餘程式碼原樣保留。確實,我使用了 DB_File 模組,但確實沒有理由不這樣做。它伴隨著每一個珀爾開箱即用安裝,因此您無需安裝它或任何東西。

如果我的雜湊值變得非常大,我會一直使用這種方法,我發現,在通過一些模糊定義的休斯點後,事情會加快很多。

相關內容