2017-06-12 4 views
0

Je travaille sur un projet de bioinformatique où je regarde de très grands génomes. Seg ne lit que 135 lignes à la fois, donc lorsque nous nourrissons les génomes, il est surchargé. J'essaye de créer une commande perl qui divisera les sections en 135 sections de ligne. La limite de caractères serait de 10 800 puisqu'il y a 80 colonnes. Voilà ce que j'ai jusqu'à présentComment est-ce que je peux diviser mes données dans des morceaux assez petits pour nourrir à Seq?

#!usr/bin/perl 
use warnings; 
use strict; 

my $str = 
'>AATTCCGG 
TTCCGGAA 
CCGGTTAA 
AAGGTTCC 
>AATTCCGG'; 



substr($str,17) = ""; 

print "$str"; 

Il se divise au 17 caractère mais seulement des impressions que la section, je veux continuer à imprimer le reste des données. Comment ajouter une commande qui permet d'afficher le reste des données. Comme il devrait se diviser à chaque 17ème caractère continuant. (puis bien sûr, je peux revenir en arrière et l'agrandir jusqu'à la taille dont j'ai réellement besoin.)

+0

Bienvenue sur stackoverflow. Jetez un oeil à [Que dois-je faire quand quelqu'un répond à ma question?] (Http://stackoverflow.com/help/someone-answers). Il y a un certain nombre d'autres pages d'aide courtes et utiles là-bas. – zdim

Répondre

0

substr renvoie la partie supprimée d'une chaîne; vous pouvez simplement l'exécuter dans une boucle:

while (length $str) { 
    my $substr = substr $str, 0, 17, ""; 
    print $substr, "\n"; 
} 
+0

Cela n'a pas d'importance pour les génomes, mais généralement '' 0 '' est une fausse valeur, donc vous voulez probablement 'while (longueur $ str)'. – melpomene

+0

@melpomene: vrai, mis à jour. – choroba

1

Je suppose que le « très grand génome » est stocké dans un fichier très volumineux, et qu'il est bien de recueillir des données par le nombre de lignes (et non par nombre de caractères) puisque c'est le premier critère mentionné.

Ensuite, vous pouvez lire le fichier ligne par ligne et assembler les lignes jusqu'à ce qu'elles soient au nombre de 135. Ensuite, les remettre à un programme ou une routine qui traite que, vider votre mémoire tampon, et continuer

use warnings; 
use strict; 
use feature 'say'; 

my $file = shift || 'default_filename.txt'; 
my $num_lines_to_process = 135; 

open my $fh, '<', $file or die "Can't open $file: $!"; 

my ($line_counter, @buffer); 

while (<$fh>) { 
    chomp; 
    if ($line_counter == $num_lines_to_process) 
    { 
     process_data(\@buffer); 
     @buffer =(); 
     $line_counter = 0; 
    } 
    push @buffer, $_; 
    ++$line_counter; 
} 

process_data(\@buffer) if @buffer; # last batch 

sub process_data { 
    my ($rdata) = @_; 
    say for @$rdata; say '---'; # print data for a test 
} 

Si votre application de traitement/routine veut une chaîne, vous pouvez ajouter à une chaîne à chaque fois au lieu d'ajouter à une tableau, $buffer .= $_; et effacer cela par $buffer = ''; au besoin.

Si vous devez transmettre une chaîne mais que vous utilisez également un tableau lors de la collecte des données (vérifications intermédiaires/élagage/traitement?), Collectez les lignes dans un tableau et utilisez-les au besoin. la remise hors tension, my $data = join '', @buffer;

Vous pouvez également utiliser la $. variable et la modulo operator (%)

while (<$fh>) { 
    chomp; 

    push @buffer, $_; 

    if ($. % $num_lines_to_process == 0) # every $num_lines_to_process 
    { 
     process_data(\@buffer); 
     @buffer =(); 
    } 
} 

process_data(\@buffer) if @buffer; # last batch 

Dans ce cas, nous devons d'abord enregistrer une ligne, puis vérifiez son numéro, depuis $. (numéro de ligne lue un handle de fichier, voir les documents liés ci-dessus) commence à partir de 1 (pas de 0).

+0

@Tvega Ajout d'un moyen plus court de le faire, édité un bit – zdim

+0

@Tvega J'ai ajouté une ligne pour traiter le dernier lot de données, à partir de la dernière fois que le tampon a été vidé jusqu'à la fin du fichier. Puisque le fichier n'est probablement pas exactement un multiple de 135 lignes qui ne sont pas traitées dans la boucle. – zdim