2012-05-23 6 views
1

J'ai un fichier Fichier1 qui contient ces données:manipulation de fichiers perl

NC_009066 5239 5308 trnA(tgc) 2.10899859667e-09 - 
NC_009066 5309 5382 trnN(gtt) 7.03000463545e-10 - 
NC_009066 5422 5487 trnC(gca) 7.09999799728e-08 - 
NC_009066 5487 5557 trnY(gta) 3.72200156562e-11 - 
NC_009066 5549 7097 cox1 291081744.81 + 
NC_009066 7109 7180 trnS2(tga) 1.83000043035e-09 - 
NC_009066 7183 7256 trnD(gtc) 2.5720000267e-09 + 

et un autre fichier FASTA Fichier2

> NC_009066,1,0-17045, 
GCTATCGTAGCTTAATTAAAGCATAACACTGAAGATGTTAAGATGAACCCTAGAAA 

J'ai mis la fichier1 dans une ligne de tableau en ligne, puis je peux accéder à chaque colonne en divisant chaque ligne sur /\s+/.

for $line(@array){ 
    @column= split(/\s+/,$line); 
    # print $column[5]."\n"; 

$gene=substr($seq,$column[1],$column[2]);#$seq extracted from File2....} 

mais je veux faire est de prendre la deuxième colonne de la 1ère ligne avec la 3ème colonne de la 2ème ligne (substr($seq,5239,5382)) puis 2ème colonne de 2e ligne et 3e colonne de 3e ligne (substr($seq,5309,5487)) ..... quelle est la meilleure façon de le faire ??

+0

Je pensais mettre les données nécessaires de @column dans le tableau 1D donc le nouveau tableau ressemblera à ceci (5239,5308, trna, -, 5309,5382, trnN, -...) donc je fais substr on $ new_array [$ i], $ new_array [$ i + 5] – Mariya

Répondre

2

Tout d'abord, notez que l'effet par défaut de split consiste à diviser $_ en espaces, en supprimant les champs vides avant et arrière. Le plus souvent c'est ce que vous voulez, et split /\s+/ est inutile. Si vous souhaitez appeler le fractionnement par défaut sur une variable autre que $_, vous devez transmettre un seul espace littéral, et non une regex, en tant qu'argument de modèle, par exemple split ' ', $line.

Je vous suggère de commencer par utiliser map pour créer un tableau contenant uniquement les données des colonnes deux et trois.

Ensuite, vous pouvez faire une boucle sur les données, en extrayant les valeurs de début et de fin et en extrayant le gène de la séquence.

Le code ressemble à ceci

use strict; 
use warnings; 

open my $fh, '<', 'f1.txt' or die $!; 

my @data = map [ (split)[1,2] ], <$fh>; 

my $seq = 'GCTATCGTAGCTTAATTAAAGCATAACACTGAAGATGTTAAGATGAACCCTAGAAA'; 

for my $i (1 .. $#data) { 
    my ($start, $end) = ($data[$i-1][0], $data[$i][1]); 
    my $gene = substr($seq, $start, $end - $start); 
    print "$gene\n"; 
} 

Notez que la boucle est sur indices 1 (l'élément secondes du tableau) à $#data (le dernier élément). C'est parce que le corps de la boucle prend la première colonne de l'élément précédent et la deuxième colonne de l'élément actuel comme une paire, et il n'y a aucun élément précédent au premier.

Notez également que vous devrez peut-être ajuster les paramètres à substr car je ne sais pas si vos indices commencent à zéro ou un, ou s'ils incluent le caractère à cet index.

Par exemple, avec $start = 1; $end = 2, substr('ATC', $start, $end - $start); retournerait T quand vous voulez dire en fait A ou AT ou TC.

+0

salut, j'ai essayé cette méthode, je pensais que cela fonctionne, mais je me suis rendu compte que la première ligne du fichier n'est pas dans le tableau cartographié @data – Mariya

+0

et c'est le code que j'ai écrit ouvrir mon $ fbed, '<', $ fichier ou die $ !; mon @data = carte [(split) [1,2,3,5]], <$fbed>; #i besoin de 1er 2e 3e et 5e colonne – Mariya

+0

Je ne comprends pas votre problème. Que faites-vous avec les nouvelles données que vous extrayez? Mon code ne fonctionnera pas si vous démarrez la boucle à zéro, car elle prend l'index * start * de l'enregistrement * précédent *, et il n'y a aucun enregistrement précédant le premier. Je vous suggère de mettre à jour votre question ou, de préférence, d'en écrire une nouvelle. – Borodin

1

Vous avez déjà tout compris vous-même, vous n'utilisez pas correctement substr. Le synopsis perldoc -f substr dit:

substr EXPR, OFFSET, LONGUEUR

mais vous lui donnez deux décalages. Au lieu de cela, soustrayez un décalage de l'autre pour calculer le paramètre de longueur correct.

+0

toute méthode pour éviter d'utiliser 2 tableaux,? – Mariya

+0

@daxim: presque, mais la question requiert également que les fichiers de début et de fin soient extraits de différents enregistrements. – Borodin

+0

bonne prise, upvote pour vous – daxim

0

Utilisez un tableau à deux dimensions:

for (my $i = 0; $i < scalar(@array); ++$i) { 
    $$table[$i] = [ split(/\s+/,$array[$i]) ]; 
} 

# you may put this into a loop 
$start = $$table[0][1]; 
$end = $$table[1][2] - $$table[0][1]; 
$gene = substr($seq, $start, $end); 

Voir aussi perllol.