• Publicidad

Contar espacios y eliminar

Perl aplicado a la bioinformática

Contar espacios y eliminar

Notapor danusol » 2011-02-09 06:12 @300

Hola.

Tengo un archivo con el siguiente formato
>GW156IX01BW18G length=114 xy=0669_2046 region=1 run=R_2011_02_01_18_40_56_
40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 33 30 28 28 28 28
>GW156IX01AUUGH length=76 xy=0234_0799 region=1 run=R_2011_02_01_18_40_56_
40 40 40 40 40 40 40 40 40 39 40 27 26 16 16 16 26 29 14 26 21 21 21 21
>GW156IX01AOII3 length=113 xy=0162_0317 region=1 run=R_2011_02_01_18_40_56_
4 9 40 40 40 40 40 40 40 40 40 39 27 27 27 40 40 40 40 40 40 40
>GW156IX01BZQTZ length=72 xy=0700_0261 region=1 run=R_2011_02_01_18_40_56_
36 40 36 33 37 32 30 27 30 26 29 15 12 12 12 11 15 16 11 11 11 18 11 11 12

y me gustaría eliminar de cada fila de números los cuatro primeros números. Mi idea inicial era eliminar los doce primeros caracteres de cada línea (cuatro números de dos dígitos más su espacio posterior).

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. while (<IN>) {
  2.   chomp;
  3.   if (/^>/) {
  4.     print OUT $_,"\n";
  5.     }
  6.   else {
  7.     $line=substr($_,12);
  8.     print OUT $line,"\n";
  9.  
  10.     }
  11. }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

pero en algunos casos los números son de un dígito como podéis ver en negrita. y por tanto no funciona en esos casos. He pensado en eliminar contando espacios en blanco, de tal manera que me elimine todo hasta él incluyendo el cuarto espacio, pero ¿cómo puedo poner esto en código?

Gracias.

D.
danusol
Perlero nuevo
Perlero nuevo
 
Mensajes: 46
Registrado: 2010-04-22 07:08 @339

Publicidad

Re: Contar espacios y eliminar

Notapor explorer » 2011-02-09 06:53 @328

Es mejor aprovecharse del hecho de que se tratan de campos separados por columnas, por lo que puedes obtener lo que quieres de forma sencilla, e independiente de cómo cambie el fichero.

Por lo que parece, lo que quieres es quitar las primeras cuatro columnas.

Esta es otra forma de hacerlo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use common::sense;
  3.  
  4. open IN,  q[<], 'kk.txt';
  5. open OUT, q[>], 'kk.txt.out';
  6.  
  7. while (my $línea = <IN>) {
  8.     given($línea) {
  9.         when(/^>/) {
  10.             print OUT $línea;
  11.         }
  12.         default {
  13.             my(undef,undef,undef,undef,$resto_línea) = split " ", $línea, 5;
  14.             print OUT $resto_línea;
  15.         }
  16.     }
  17. }
  18.  
  19. close IN;
  20. close OUT;
  21.  
  22. __END__
  23. >GW156IX01BW18G length=114 xy=0669_2046 region=1 run=R_2011_02_01_18_40_56_
  24. 40 40 40 40 40 40 40 40 40 40 40 40 40 40 33 30 28 28 28 28
  25. >GW156IX01AUUGH length=76 xy=0234_0799 region=1 run=R_2011_02_01_18_40_56_
  26. 40 40 40 40 40 39 40 27 26 16 16 16 26 29 14 26 21 21 21 21
  27. >GW156IX01AOII3 length=113 xy=0162_0317 region=1 run=R_2011_02_01_18_40_56_
  28. 40 40 40 40 40 40 40 39 27 27 27 40 40 40 40 40 40 40
  29. >GW156IX01BZQTZ length=72 xy=0700_0261 region=1 run=R_2011_02_01_18_40_56_
  30. 37 32 30 27 30 26 29 15 12 12 12 11 15 16 11 11 11 18 11 11 12
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Comentarios: usamos split() para que corte la $línea en cinco partes (cortando por los espacios en blanco). Las cuatro primeras son desechadas (asignadas a undef es lo mismo que tirarlas a la basura). Pero la quinta es lo que contiene la línea desde el quinto campo hasta el final, por lo que ahí tenemos el $resto_línea, que sacaremos fuera.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Contar espacios y eliminar

Notapor danusol » 2011-02-09 09:41 @445

¡Fenomenal solución! Muchas gracias, explorer.
danusol
Perlero nuevo
Perlero nuevo
 
Mensajes: 46
Registrado: 2010-04-22 07:08 @339

Re: Contar espacios y eliminar

Notapor Leo_Gutierrez » 2011-02-10 01:12 @092

Hola, solo por agregar, tal vez te sirva algo como esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open(my $file, q[<], "file.txt") or die("Error abriendo archivo. $!");
  2. open(my $salida, q[>], "salida.txt") or die $!;
  3.  
  4. while(<$file>)
  5. {
  6.         if(/^>/) {
  7.                 print $salida "\n$_";
  8.         } else {
  9.                 print $salida (m/\d+\s\d+\s\d+\s\d+\s(.*)/);
  10.         }
  11. }
  12.  
  13. close($file);
  14. close($salida);
  15.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


o incluso:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. m/^>/ ? print $salida "\n$_" : print $salida (m/\d+\s\d+\s\d+\s\d+\s(.*)/) while(<$file>);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Ah, cada vez me gusta más Perl :D

Saludos.
Leo_Gutierrez
Perlero nuevo
Perlero nuevo
 
Mensajes: 91
Registrado: 2008-08-20 23:38 @026

Re: Contar espacios y eliminar

Notapor explorer » 2011-02-10 05:22 @265

Ya te digo... creo que es la primera vez en mi vida que veo usar una expresión regular de esa manera...

Requiere un poco de explicación, para el neófito.

Una expresión regular, en contexto escalar, devuelve verdadero o falso, indicando si el patrón de búsqueda ha coincidido o no con la cadena de prueba. Pero, en contexto de lista, devuelve todos los elementos capturados por los paréntesis de captura.

En este caso, la cadena de prueba es la variable por defecto, $_, aunque no se vea. Y el contexto es de lista, gracias a los paréntesis que rodean a la expresión regular.

Los paréntesis devuelven todos los elementos capturados, que en este caso solo es uno (el resto de la línea a partir de la quinta columna), así que lo que recibe print() no es un escalar (un trozo de cadena), sino una lista de valores compuesto por un único valor, que es el trozo de cadena.

Bueno, el caso es que obtenemos lo que queremos, aunque de forma poco común. Pero válida.

Solo comentar, finalmente, que se puede reescribir esa expresión regular a algo como esto: m/(?:\d+\s+){4}(.*)/. El '(?:...)' indica sólo agrupamiento, no captura. Y el '{4}' indica el número de repeticiones de lo que le precede.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Contar espacios y eliminar

Notapor Leo_Gutierrez » 2011-02-10 11:49 @534

explorer escribiste:Ya te digo... creo que es la primera vez en mi vida que veo usar una expresión regular de esa manera...


No sé si eso es bueno o malo.

Sé que la sentencia es algo críptica o algo difícil de leer, y claro, no es recomendable usarla pero solo la uso para aprender. Un amigo programador me recomendó que tratara de usar éstas solo por aprender, porque frecuentemente son las que exigen más análisis.

explorer escribiste:Solo comentar, finalmente, que se puede reescribir esa expresión regular a algo como esto: m/(?:\d+\s+){4}(.*)/. El '(?:...)' indica sólo agrupamiento, no captura. Y el '{4}' indica el número de repeticiones de lo que le precede.


No sabía que se pudieran usar así, sin duda queda más bonito.

Saludos.
Leo_Gutierrez
Perlero nuevo
Perlero nuevo
 
Mensajes: 91
Registrado: 2008-08-20 23:38 @026


Volver a Bioinformática

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron