2017-01-24 5 views
0

Je veux ajouter un code dans le script suivant pour éliminer ces fichiers de sortie vides.éliminer les fichiers vides dans un sous-programme en perl

Le script convertit un seul fichier fastq ou tous les fichiers fastq d'un dossier au format fasta, tous les fichiers fasta de sortie conservent le même nom que le fichier fastq; le script présente une option pour exclure toutes les séquences qui présentent un nombre déterminé de répétitions NNN (NNNNNNNNNNNNNNNNNNATAGTGAAGAATGCGACGTACAGGATCATCTA), j'ai ajouté cette option car certaines séquences ne présentent que NNNNN dans les séquences, exemple: si l'option -n est égale à 15 (-n 15) il exclura toutes les séquences qui présentent 15 ou plus de répétitions N, à ce point le code fonctionne bien, mais il génère des fichiers vides (dans ces fichiers fastq que toutes les séquences présentes 15 répétitions N ou plus sont exclues). Je veux éliminer tous les fichiers vides (sans séquences) et ajouter le nombre de fichiers qui ont été éliminés car ils étaient vides.

code:

#!/usr/bin/env perl 
use strict; 
use warnings; 
use Getopt::Long; 

my ($infile, $file_name, $file_format, $N_repeat, $help, $help_descp, 
    $options, $options_descrp, $nofile, $new_file, $count); 

my $fastq_extension = "\\.fastq"; 

GetOptions (
    'in=s'  => \$infile, 
    'N|n=i'  =>\$N_repeat, 
    'h|help' =>\$help, 
    'op'  =>\$options 
); 

# Help 

$help_descp =(qq(    
       Ussaje: 
       fastQF -in fastq_folder/ -n 15 
         or 
       fastQF -in file.fastq -n 15 
      )); 

$options_descrp =(qq(

      -in  infile.fastq or fastq_folder/     required 
      -n  exclude sequences with more than N repeat  optional 
      -h  Help description        optional 
      -op  option section         optional 
        )); 

$nofile =(qq(
      ERROR: "No File or Folder Were Chosen !" 

       Usage: 
        fastQF -in folder/ 

       Or See -help or -op section 
      )); 

# Check Files 

    if ($help){ 
     print "$help_descp\n"; 
     exit; 
    } 
    elsif ($options){ 
     print "$options_descrp\n"; 
     exit; 
    } 

    elsif (!$infile){ 
     print "$nofile\n"; 
     exit; 
    } 


#Subroutine to convert from fastq to fasta 

    sub fastq_fasta { 

     my $file = shift; 
     ($file_name = $file) =~ s/(.*)$fastq_extension.*/$1/; 

# eliminate old files 

     my $oldfiles= $file_name.".fasta"; 

     if ($oldfiles){ 
      unlink $oldfiles; 
     } 

     open LINE, '<', $file    or die "can't read or open $file\n"; 
     open OUTFILE, '>>', "$file_name.fasta" or die "can't write $file_name\n"; 

     while (
      defined(my $head = <LINE>)  && 
      defined(my $seq  = <LINE>)  && 
      defined(my $qhead = <LINE>)  && 
      defined(my $quality = <LINE>) 
     ) { 
       substr($head, 0, 1, '>'); 


       if (!$N_repeat){ 
        print OUTFILE $head, $seq; 


       } 

       elsif ($N_repeat){ 

         my $number_n=$N_repeat-1; 

        if ($seq=~ m/(n)\1{$number_n}/ig){ 
         next; 
        } 
        else{ 
         print OUTFILE $head, $seq; 
        } 
       } 
     } 

     close OUTFILE; 
     close LINE; 
    } 

# execute the subrutine to extract the sequences 

    if (-f $infile) {   # -f es para folder !! 
     fastq_fasta($infile); 
    } 
    else { 
     foreach my $file (glob("$infile/*.fastq")) { 
     fastq_fasta($file); 
     } 
    } 

exit; 

J'ai essayé d'utiliser le code suivant à l'extérieur du sous-programme (avant la sortie), mais il fonctionne juste pour le dernier fichier:

$new_file =$file_name.".fasta"; 
     foreach ($new_file){ 

      if (-z $new_file){ 
       $count++; 
       if ($count==1){ 
        print "\n\"The choosen File present not sequences\"\n"; 
        print " \"or was excluded due to -n $N_repeat\"\n\n"; 

       } 
       elsif ($count >=1){ 
        print "\n\"$count Files present not sequences\"\n"; 
        print " \" or were excluded due to -n $N_repeat\"\n\n"; 

       } 

       unlink $new_file; 
      } 
     } 

et je viens d'essayer quelque chose de similaire à l'intérieur du sous-programme mais ce dernier code ne fonctionne pas !!!!

Un conseil?

Merci beaucoup!

+4

Votre boucle foreach exécute une seule fois parce que new_file $ est une valeur scalaire unique, pas une liste de valeurs. – toolic

Répondre

0

vous devriez vérifier, si quelque chose a été écrit dans votre nouveau fichier à la fin de notre sous-programme fastq_fasta. Il suffit de mettre votre code après la déclaration close OUTFILE:

close OUTFILE; 
close LINE; 

my $outfile = $file_name.".fasta"; 
if (-z $outfile) 
{ 
    unlink $outfile || die "Error while deleting '$outfile': $!"; 
} 

De plus, il sera préférable d'ajouter la déclaration die/warn également à l'autre ligne de unlink. Les fichiers vides doivent être supprimés.

Peut-être une autre solution si vous n'êtes pas fixé à Perl, mais autorisé à utiliser sed et une boucle bash:

for i in *.fastq 
do 
    out=$(dirname "$i")/$(basename "$i" .fastq).fasta 
    sed -n '1~4{s/^@/>/;N;p}' "$i" > "$out" 
    if [ -z $out ] 
    then 
     echo "Empty output file $out" 
     rm "$out" 
    fi 
done 

Hope that helps!

Meilleur Frank

+0

merci beaucoup !! –

0

La meilleure chose à faire est probablement ajouter un compteur à votre sous-routine pour garder une trace du nombre de séquences dans le fichier de sortie:

sub fastq_fasta { 
    my $counter1 = 0; 
    my $file = shift; 
    ($file_name = $file) =~ s/(.*)$fastq_extension.*/$1/; 

# eliminate old files 

    my $oldfiles= $file_name.".fasta"; 

    if ($oldfiles){ 
     unlink $oldfiles; 
    } 

    open LINE, '<', $file    or die "can't read or open $file\n"; 
    open OUTFILE, '>>', "$file_name.fasta" or die "can't write $file_name\n"; 

    while (
     defined(my $head = <LINE>)  && 
     defined(my $seq  = <LINE>)  && 
     defined(my $qhead = <LINE>)  && 
     defined(my $quality = <LINE>) 
    ) { 
      $counter1 ++; 
      substr($head, 0, 1, '>'); 


      if (!$N_repeat){ 
       print OUTFILE $head, $seq; 


      } 

      elsif ($N_repeat){ 

        my $number_n=$N_repeat-1; 

       if ($seq=~ m/(n)\1{$number_n}/ig){ 
        $counter1 --; 
        next; 
       } 
       else{ 
        print OUTFILE $head, $seq; 
       } 
      } 
    } 

    close OUTFILE; 
    close LINE; 
    return $counter1; 
} 

Vous pouvez supprimer des fichiers lorsque le nombre de retour est égal à zéro:

if (-f $infile) {   # -f es para folder !! 
    fastq_fasta($infile); 
} 
else { 
    foreach my $file (glob("$infile/*.fastq")) { 
     if (fastq_fasta($file) == 0) { 
      $file =~ s/(.*)$fastq_extension.*/$1.fasta/; 
      unlink $file; 
     } 
    } 
} 
+0

merci beaucoup !! –