probleme supprimer redondance dans un fichier
Bonjour à tous,
Je viens sur le forum C car j'ai un problème.
J'ai un fichier qui ressemble à cela :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| >seq1
ACTTTCCACAACGATGGAAGATGATGA
>seq2
ACTTTCCACAACGATGGAAGATGATGAA
>seq3
ATTCCACAACGATGGAAGATGATGAA
>seq4
CTTTCCACAACGATGGAAGATGATGAA
>seq5
NTCCACAACGATGGAAGATGATGAAGA
>seq6
TACTTTCCACAACGATGGAAGATGATGA
>seq7
TACTTTCCACAACGATGGAAGATGATGAA
>seq8
TCCACAACGATGGAAGATGATGA
>seq9
AAAGAAGAAATTGAATAAATATATGTC
>seq10
AAAGAAGAAATTGAATAAATATATGT
>seq11
AAAGAAGAAATTGAATAAATATATGTCA
>seq12
AAAGAAGAAATTGAATAAATATAT
>seq13
AAAGAAGAAATTGAATAAATATATG
>seq14
AAAGAAGAAATTGAATAAATATA |
Je souhaiterai trouver la séquence la plus petite que toutes ces séquences partagent entre elle (en gras dans mon exemple), et donc la seule séquence que j'aimerai récupérer est la seq 8 et seq14
Code:
1 2 3 4
| >seq8
TCCACAACGATGGAAGATGATGA
>seq14
AAAGAAGAAATTGAATAAATATA |
J'ai ce script perl qui fonctionne très bien sur un petit jeu de données:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| #!/usr/bin/perl
# Input file: a fasta file
# Output file: a unique fasta file
# Command line: perl test.pl infile.fasta
use strict;
use warnings;
use List::MoreUtils qw(uniq);
#read the file into a hash
my %hash;
my $title;
my $infile=shift or die "give me a infile\n";
open (IN,"$infile");
while (<IN>){
$_=~s/\n//;
$_=~s/\r//;
if ($_=~/>/){
$title=$_;
$title=~s/>//;
}
else{
$hash{$_}=$title;
}
}
print "hash ok \n";
close IN;
#remove the abundant sequences
my @sort_all_seq = sort {length($a) <=> length($b)} keys (%hash);
print "sort ok \n";
my @uniqueseq;
my $find=0;
foreach my $seqs (@sort_all_seq){
$find=0;
my $seq=uc($seqs); #uppercase (retourne la chaine en majuscule)
foreach (@uniqueseq){
if ($_=~/$seq/){ # si ma sequence contient
$_=$seq; #remplace avec la plus petite sequence
$find=1;
last;
}
if ($seq=~/$_/){
$find=1;
# ajout d'un last ici ?
}
}
if ($find==0){
push @uniqueseq,$seq;
}
}
print "writing ....\n";
my @final = uniq @uniqueseq;
#outout the final result
open (OUT,">tmp.fa");
foreach (@final){
print OUT ">$hash{$_}\n$_\n";
}
close OUT; |
Mais malheureusement, j'ai un fichier avec plus de 2 millions de séquences, et cela fait 4 jours que mon script toune sur un serveur ( disques : 6To brut, mémoire vive : 16Go) ... je trouve que cela est très long, et je voulais savoir si vous pensiez qu'en langage C , cela pouvait aller plus vite ?
Pb : je ne sais pas coder en C !