• Publicidad

Extracción de líneas coincidentes

Perl aplicado a la bioinformática

Extracción de líneas coincidentes

Notapor Kuronno » 2012-12-09 20:20 @889

Hola,
he hecho un script que me permite abrir el archivo "funcions.txt" donde solo me interesan las líneas que contengan "glycolisis" o "neogenesis" porque llevan un código que necesito posteriormente.

Una vez consigo esta información quiero leer el archivo "lee.txt" para extraer de él las líneas que contengan los códigos anteriores y guardarlos en:

- GL.txt: si contiene los códigos de glycolisis
- NL.txt: si contiene los códigos de neogenesis

El script que he ideado es el siguiente:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use strict;
  2. open( arxiu,  "funcions.txt" ) or die("No el puc obrir");
  3. open( arxiu1, "lee.txt" )      or die("No el puc obrir!");
  4. open( arxiu2, ">GL.txt" )      or die("el GL no s'obre");
  5. open( arxiu3, ">NL.txt" )      or die("el GL no s'obre");
  6. while (<arxiu>) {
  7.  
  8.     my @llista = split( /\t/, $_ );
  9.     if ( $llista[1] =~ /glycolysis/ ) {
  10.  
  11.         my @gensGL = $llista[0];
  12.  
  13.     }
  14.     if ( $llista[1] =~ /neogenesis/ ) {
  15.  
  16.         my @gensNL = $llista[0];
  17.     }
  18.  
  19.     while (<arxiu1>) {
  20.         my @llista2 = split( /\t/, $_ );
  21.  
  22.         if ( $llista2[1] eq $gensGL[0] ) {
  23.             print arxiu2 "$_";
  24.         }
  25.         if ( $llista2[1] eq $gensNL[0] ) {
  26.             print arxiu3 "$_";
  27.         }
  28.     }
  29. }
  30. close(arxiu)  or die("no el puc tancar");
  31. close(arxiu1) or die("no el puc tancar");
  32. close(arxiu2) or die("no el puc tancar");
  33. close(arxiu3) or die("no el puc tancar");
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Por desgracia me sale error: requires explicit package name (refiriéndose a @gensNL y @gensGL dentro de los últimos dos "if" del script). No consigo solventar este problema y me gustaría saber si seríais tan amables de ayudarme.

Muchas gracias,

Kuronno.
Última edición por explorer el 2012-12-09 20:32 @897, editado 1 vez en total
Razón: Formateado de código con Perltidy y poner marcas Perl
Kuronno
Perlero nuevo
Perlero nuevo
 
Mensajes: 3
Registrado: 2012-03-07 06:59 @333

Publicidad

Re: Extracción de líneas coincidentes

Notapor explorer » 2012-12-09 21:07 @921

Fíjate lo que le estás pidiendo hacer a Perl:
  • en la línea 6 lees una línea del archivo funcions.txt
  • luego, en las líneas 19 a 28 lees el archivo lee.txt entero, línea a línea
entonces, cuando se repite el bucle de la línea 6 para la siguiente línea de funcions.txt, al llegar a la línea 19 se encuentra con que no puede leer las líneas de lee.txt, ya que fueron leídos todas antes.

El error dice que en las líneas 22 y 25 haces referencia a las variables @gensGL y @gensNL, y Perl no sabe dónde fueron declaradas ni definidas.

El problema está en que en las líneas 11 y 16 las estás declarando y definiendo con un valor, pero locales al contexto (las llaves) que las rodean. Por ejemplo: en la línea 11 estás declarando un nueva variable llamada @gensGL (usando el operador my()), y le das un valor inicial (el primer elemento de @llista). Pero, en cuanto Perl llega a la línea 13, se olvida de ella, porque al declararla con my(), le indicaste a Perl que esa variable debía ser local al contexto en donde se encuentra (las llaves de las líneas 9 y 13).

La solución mejor para este problema sería leer en memoria uno de los dos archivos, y luego recorrer el otro, y si se cumple la condición que impongamos, grabar el resultado en un archivo o en otro.

Por estos foros hay problemas parecidos ya resueltos. Por ejemplo: Comparar líneas entre archivos.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Extracción de líneas coincidentes

Notapor Kuronno » 2012-12-10 05:41 @278

En primer lugar, muchas gracias por tu respuesta. Desconocía que mi error fuera tan grave.
Desconozco cómo puedo leer en memoria uno de los dos archivos y recorrer el otro. Nunca he hecho una instrucción así en un contexto de este tipo. Por ese motivo estoy bloqueado y aún consultando por los enlaces que me has añadido no consigo solucionarlo.
¿Me podrías poner un ejemplo de cómo sería?
Muchas gracias.
Kuronno
Perlero nuevo
Perlero nuevo
 
Mensajes: 3
Registrado: 2012-03-07 06:59 @333

Re: Extracción de líneas coincidentes

Notapor explorer » 2012-12-10 13:15 @594

Esta es una posible solución, pero no sé si funciona ya que no sabemos muy bien el formato real de los archivos. Solo sabemos que se componen de campos separados por tabuladores, pero no sabemos si los id se repiten o no.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5. use autodie;            # Es mejor morir que regresar con deshonor --Proverbio Klingon
  6.  
  7. ## Abrimos el primer archivo y leemos los códigos
  8. open my $ARXIU, '<', 'funcions.txt';
  9.  
  10. my(%gensGL, %gensNL);                   # aquí guardamos los códigos
  11.  
  12. while (<$ARXIU>) {
  13.     my($id,$funcion) = split /\t/;
  14.  
  15.     if ($funcion =~ /glycolysis/) {
  16.         $gensGL{$id} = 1;               # recordamos ese código
  17.     }
  18.     if ($funcion =~ /neogenesis/) {
  19.         $gensNL{$id} = 1;               # recordamos ese código
  20.     }
  21. }
  22.  
  23. close $ARXIU;
  24.  
  25.  
  26. ## Leemos el segundo archivo, desviando las líneas hacia las salidas
  27. open my $ARXIU1, '<', 'lee.txt';
  28. open my $GL,     '>', 'GL.txt';
  29. open my $NL,     '>', 'NL.txt';
  30.  
  31. while (<$ARXIU1>) {
  32.     my(undef,$id) = split /\t/;
  33.  
  34.     if (exists $gensGL{$id}) {          # si existe un código de glycolysis para ese $id,
  35.         print $GL $_;                   # mandamos la línea al archivo correspondiente
  36.     }
  37.     if (exists $gensNL{$id}) {          # si existe un código de neogenesis para ese $id,
  38.         print $NL $_;                   # mandamos la línea al archivo correspondiente
  39.     }
  40. }
  41. close $ARXIU1;
  42. close $GL;
  43. close $NL;
  44.  
  45.  
  46. __END__
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Bioinformática

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados