탭으로 구분된 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 모듈을 사용했지만 사용하지 않을 이유가 전혀 없습니다. 그것은 모든 것을 동반한다진주별도의 설치가 필요하지 않도록 즉시 설치됩니다.
해시가 매우 커지면 나는 항상 이 방법을 사용하는데, 모호하게 정의된 휴즈 지점을 통과한 후에 속도가 크게 빨라지는 것을 발견했습니다.