Bienvenida a los foros de Perl en Español, alondra.
Realmente, no necesitas, para nada, guardar la información en un array de dos dimensiones. ¿Por qué? Pues porque puedes realizar la búsqueda de la información sin guardar nada, simplemente ir leyendo línea a línea el fichero de entrada.
Más detalle:
1.- Preguntas al usuario qué es lo que quieres buscar
2.- Abres el fichero
3.- Bucle por todas las filas. Por cada fila...
4.- Extraemos los campos que nos interesan, desde la fila
5.- Si la fila contiene lo que queremos, imprimimos el resultado
6.- Terminamos (si sabemos que no hay más filas con los mismos datos de búsqueda), o seguimos con la siguiente fila.
Otra cosa es si quieres que el usuario busque más de una vez. Entonces sí que merece la pena guardar la información. Pero aún así, tampoco necesitas crear un array de dos dimensiones. Te vale con guardar las filas del fichero de la misma manera en que lo haces ahora, en el array @archivo. Por lo tanto, quedaría así.
1.- Leer el fichero, en filas, al array @fichero
2.- Bucle, mientras que el cliente no marque el final
3.- Leemos lo que quiere buscar
4.- Repetimos el bucle descrito antes, por el array @archivo
5.- Lo demás, igual.
6.- Volvemos al 2.
Aún así, si quieres guardar la información en un array multidimensional, debes entender cómo crearlos y manejarlos. En
perldoc perllol tienes una explicación de cómo entenderlos. El problema es que, si no se tiene cuidado, la sintaxis de Perl puede asustar bastante. Y también hay que prestar atención a los detalles.
Esta es una forma de crear una matriz de dos por dos elementos:
Using perl Syntax Highlighting
my @matriz = (
[ 1
, 2
],
[ 3
, 4
],
);Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
Ahora puedes acceder al primer elemento de la segunda fila:
Using perl Syntax Highlighting
print $matriz[1
]->[0
];Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
El operador flecha, cuando está entre [] y {}, se puede obviar, así que podemos dejarlo en
Using perl Syntax Highlighting
print $matriz[1
][0
];Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
que entonces se parece mucho a la sintaxis del lenguaje C. Necesitamos seguir poniendo el '$' delante porque estamos recuperando un solo elemento, no varios.
Decía que hay que prestar atención a los detalles. La definición del array lo hemos hecho, primero, usando paréntesis, porque, efectivamente, estamos creando un array. Pero luego, dentro, estamos usando corchetes. Cada par de ellos, está creando un nuevo array anónimo (no tiene nombre), del que Perl obtiene su referencia, que es al final, lo que se almacena en el array. Por eso se dice que un array de arrays es, en realidad, un array de referencias a arrays. Esto es exactamente lo que también se hace en C.
Ahora que tenemos un array, podemos, por ejemplo, agregarle una nueva línea:
Using perl Syntax Highlighting
push @matriz, [ 5
, 6
];Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
Usamos push(), para agregar un nuevo elemento a un array. Y ese elemento es una referencia a un nuevo array (los corchetes) que tiene dos elementos.
En cuanto a tu programa, hay varios errores:
* las líneas 41 y 43 deberían estar al revés: primera partes el último campo, y luego recorres sus valores
* las líneas que preguntan al usuario por lo que quieren buscar deben estar fuera del bucle que recorre las líneas, porque entonces pasa lo que dices: que solo ha encontrado la información de la primera línea
* por último, hay un problema, mucho más grave, si los datos contienen acentos, pero como veo en el código que se trata de genes, no creo que exista ese problema.
Una solución podría ser esta:
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
open(ARCHIVO, 'file.gff');
my @archivo = <ARCHIVO>;
close(ARCHIVO);
chomp(@archivo); # quitamos los finales de línea
my $que_buscamos = '';
do {
if ($que_buscamos) { # si hay algo que buscar...
for my $linea (@archivo) { # para todas las líneas del @archivo
my @campos = split( /\t/, $linea ); # dividir en campos
my @nombres = split( /;/, $campos[-1]); # dividir último campo
for my $nombre (@nombres) { # recorremos los nombres
if ($nombre eq $que_buscamos) {
print "El gen $nombre se encuentra en el lugar $campos[0]\n";
}
}
}
}
print "Deme un nombre: ";
$que_buscamos = <STDIN>;
chomp $que_buscamos;
} while ($que_buscamos ne 'fin');
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
Pero esto lo que hace es extraer la información de las líneas cada vez que queremos buscar algo. Lo mejor es guardar la información en un array:
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
open(ARCHIVO, 'file.gff');
my @archivo = <ARCHIVO>;
close(ARCHIVO);
chomp @archivo;
my @lineas;
foreach my $linea (@archivo) {
my @campos = split( /\t/, $linea ); # 9 columnas
push @lineas, [ @campos ];
}
#use Data::Dumper;
#print Dumper \@lineas;
my $que_buscamos = '';
do {
if ($que_buscamos) { # si hay algo que buscar...
for my $linea (@lineas) { # para todas las líneas...
my @nombres = split( /;/, $linea->[-1]); # dividimos el último campo
for my $nombre (@nombres) { # recorremos los nombres
if ($nombre eq $que_buscamos) {
print "El gen $nombre se encuentra en el lugar $linea->[0]\n";
}
}
}
}
print "Deme un nombre: ";
$que_buscamos = <STDIN>;
chomp $que_buscamos;
} while ($que_buscamos ne 'fin');
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
En este caso, estamos creando un array bidimensional. En @lineas guardamos, con push(), una línea cada vez, y en esa línea guardamos un único elemento: una referencia a un array anónimo, que a su vez contiene todos los @campos de la $linea leída.
Ahora bien... la búsqueda también lo podemos hacer con expresiones regulares, pues lo que buscamos es un nombre dentro de otros tres. Solo nos interesa saber si está o no.
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
open(ARCHIVO, 'file.gff');
my @archivo = <ARCHIVO>;
close(ARCHIVO);
chomp @archivo;
my @lineas;
foreach my $linea (@archivo) {
my @campos = split( /\t/, $linea );
push @lineas, [ @campos ];
}
#use Data::Dumper;
#print Dumper \@lineas;
my $que_buscamos = '';
do {
if ($que_buscamos) { # si hay algo que buscar...
for my $linea (@lineas) { # para todas las líneas...
if ($linea->[-1] =~ /$que_buscamos/) { # si el último campo contiene lo $que_buscamos
print "El gen $que_buscamos se encuentra en el lugar $linea->[0]\n";
}
}
}
print "Deme un nombre: ";
$que_buscamos = <STDIN>;
chomp $que_buscamos;
} while ($que_buscamos ne 'fin');
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4