
タブで区切られた複数のfastqファイルがあります。毎回読み取る 2 行目を一致させ、一致する場合は、横に値を追加します。たとえば、
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つのファイルだけをメモリにロードすると、メモリが節約されると思いましたが、そうすることはできません。私のスクリプトを修正するのに役立ちます。
答え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モジュールを使用しましたが、使用しない理由はまったくありません。それはすべてを伴う真珠別途の設置が不要となるよう、直ちに設置されます。
ハッシュが非常に大きくなると、私はいつもこの方法を使いましたが、あいまいに定義されたヒューズポイントを通過した後に速度が大幅に速くなることがわかりました。