preiddy escribiste:my $base = do { local $/; open(BASE,"<pubmed-result.txt"); <BASE> };
¿qué facilidades o ventajas ofrece hacerlo así?
Con
while es fácil de entender y de usar y es la forma recomendada, ya que a veces trabajamos con ficheros enormes que no caben en memoria, por lo que es normal leer línea a línea y trabajar con cada una.
En el caso de que el fichero sí entre en memoria -y tengamos que trabajar con todo él-, entonces hay varias opciones para leerlo completamente (si ese es nuestro deseo). Una de ellas es la mostrada: indefinimos el separador de registros de entrada
$/ (por defecto vale lo mismo que un '\n' del sistema) -esto quiere decir que... en realidad el fichero que vamos a leer... NO tiene registros... que es lo mismo que decir que... nos lo vamos a leer todo de una sola vez-; luego lo abrimos con open() y luego lo leemos con '<>'. De esta forma leemos el fichero a una variable e$calar.
Otra forma es esta:
my @base = do { open(BASE,"<pubmed-result.txt"); <BASE> };Es casi lo mismo, pero no... aquí abrimos el fichero de forma normal y... ejecutamos la lectura del fichero con '<>'. El
operador diamante por defecto funciona en contexto de lista, por lo que devolverá un
array con todos los valores (líneas) del fichero, que quedará asignado a nuestra @rray.
How can I read in an entire file all at once? slurp file, slurping.
preiddy escribiste:my ($valor) = $registro =~ /^$campo_actual (.+?)^$campo_siguiente /ms;
¿cómo se extrae el valor?
Queda claro que $campo_actual y $campo_siguiente son los campos que estamos buscando -bueno, en realidad queremos lo que está entre los dos-. Cada uno de ellos contienen dos letras en mayúscula.
La expresión regular entonces quiere decir: "Busca (
=~) en
$registro aquella línea -pues contiene más de una (
/m)-, que comienza (
^) por nuestro
$campo_actual, seguido de un espacio en blanco, seguido por un conjunto de caracteres (
.+) -incluido el retorno de carro (
/s)-, pero lo menos posible (
?) para llegar a la siguiente línea que empieza (
^) por el
$campo_siguiente seguido de un espacio en blanco. Devuelve el conjunto de caracteres encontrados (
()) a la variable $1.
Pero como el usuario nos pide un
array (
($valor)), también lo devolvemos como primer valor de ese array".
preiddy escribiste:Si se tiene un archivo de texto con una estructura similar al expuesto en mensajes anteriores, donde cada registro va en una linea, solo con cambiarle los tag seria suficiente para que pueda ser analizado, o eso es lo que creía, pero al hacerlo me imprime algo totalmente diferente a lo que esperaba.
En el programa que te mandé hay que hacer varios cambios, entonces:
- @campos debe contener los campos que hay dentro del registro Y en el orden en que aparecen
- %campos debe contener la correspondencia de esos campos a los de la base de datos
- En el while, indicar los campos inicio y fin de registro.
preiddy escribiste:Donde PMID y SO se pueden tomar como inicio y final de campo, hago el respectivo cambio en la línea:
while ( $base =~ /(^PMID.+?^SO.+?)/smg )
ejecuto y esto es lo que imprime:
No importa el tamaño de los campos (2 o 4 letras), lo importante es el orden en que están escritos en @campos.
preiddy escribiste:Solo quería ver cómo lo imprimía, y después de darle varias vueltas al script para tratar de ajustarlo a este nueva estructura, detecté que esta variante de archivo duplica las marcas de los campos cuando tiene más de un valor, es decir, por cada autor le asigna al comienzo la marca AU -. ¿Esa duplicidad de marca puede tener algo que ver con que no reconoce o procesa correctamente el archivo?
Pues sí. El problema es completamente distinto. Si son pocos campos que hacen la duplicidad, entonces hay que plantearlo desde otro punto de vista.
Quizás entonces lo más cómodo es volver a recorrer el registro línea a línea e ir almacenando valores con el mismo valor de campo. Luego, sigue igual que antes a la hora de crear la sentencia sql.
preiddy escribiste:Por último y con esto dejo de dar la lata, este nuevo archivo lo puedo obtener en XML, pero con menos datos que uno de txt, ¿existe una librería de perl que pase directamente del xml a base de datos? Porque lo que sí he visto es de base de datos a xml.
Directamente, creo que no, pero con los módulos
XML::Simple y
XML::Twig (sobre todo este último) te pueden ayudar bastante.
De todas formas, hay módulos como
AnyData::Format::XML que manejan los xml como si fueran bases de datos, por lo que es más fácil aún el pasarles a otra base de datos (incluso no pasarles
).
Actualización: Entra en
XML::RDB y busca por 'A Sample Run using MySQL'.
Sí que hay módulos... sólo es cuestión de buscarlos