• Publicidad

Leer el último elemento de una frase del fichero

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Leer el último elemento de una frase del fichero

Notapor zangre » 2010-06-22 04:48 @242

Hola de nuevo, ya estoy aquí a la carga otra vez. :roll:

Veamos, tengo un fichero con un montón de datos (el que tengo que importar a un MySQL), y quiero que no sea sólo para ese fichero sino para todos y así generalizar un poco el código. El fichero, son datos sobre investigaciones científicas y cuando el dato no ha sido posible sacarlo, lo señalan con un "-".

Por el momento, todos los datos que no están al final de línea, los detecto tranquilamente con un dato eq '-' y los paso a NULL. El problema viene en todos los guiones que están al final de la linea, que no los reconoce y me pone el dichoso guioncito en el MySQL.

Pongo el código:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/Applications/XAMPP/xamppfiles/bin/perl
  2. use ConectarDB;
  3. use strict;
  4. use warnings;
  5. use Data::Dumper;
  6. use DBI;
  7.  
  8. #Abro, recojo los datos y cierro el fichero
  9. open (FICHERO, "<TaulaDefinitiva.txt") or die "ERROR: No se encuentra el fichero texto.txt\n";
  10. my @texto = <FICHERO> or die "ERROR: No puedo leer el fichero\n";
  11. close FICHERO or die "ERROR: No se puede cerrar el fichero\n";
  12.  
  13. #Separo el el texto, en los diferentes elementos (separados con comas)
  14. my @lineas;
  15. foreach ( @texto ) {
  16.   push @lineas, [ split /,/];
  17. }
  18.  
  19. #Inicio y conecto con mysql
  20. my($dbh,$sth);
  21. $dbh = ConectarDB->connect();
  22.  
  23. #Código html
  24. print "Content-type: text/html\n\n";
  25. print "<html>\n";
  26. print "<body bgcolor=#CCCCCC>\n";
  27. print "miau<br><br><br><br><br>\n";
  28.  
  29. my ($columnes, $query);
  30.  
  31. #Recorro el texto del fichero
  32. for (my $j  = 0;  $j < @lineas; $j++ )
  33. {
  34.   #Si es primera fila, recogemos el nombre de las columnas
  35.     if($j == 0) {
  36.       #Borramos la tabla anterior si existía
  37.          eval { $dbh->do("DROP TABLE IF EXISTS tablaPrueba") };
  38.             print "Dropping tablaPrueba failed: $@\n" if $@;
  39.        
  40.         #Creamos una nueva tabla, $query será la sentencia para crearla.  
  41.         $query = "CREATE TABLE tablaPrueba (";
  42.        #Recogemos los nombres de las columnas del array
  43.         for (my $k = 0; $k < @{$lineas[$j]}; $k++ )
  44.         {
  45.           #Si estamos en en la última posición, evitar la ,
  46.           if ($k == @{$lineas[$j]}-1)
  47.           {
  48.             $query = $query.$lineas[$j][$k]." VARCHAR(20) NULL";
  49.             $columnes = $columnes.$lineas[$j][$k];
  50.           }
  51.           #Si estamos en cualquier otra posición, hemos de poner la ,
  52.           else
  53.           {
  54.             $query = $query.$lineas[$j][$k]." VARCHAR(20) NULL,";
  55.             $columnes = $columnes.$lineas[$j][$k].",";
  56.           }
  57.        
  58.         }
  59.         #Terminar la sentencia de crear una base de datos
  60.         $query = $query.")";
  61.        
  62.         #Conectamos y creamos la bbdd
  63.         $sth = $dbh->prepare($query) or die("Couldn't prepare statement: " . $dbh->errstr);
  64.         $sth->execute();
  65.         $sth->finish;
  66.        
  67.                                
  68.     }
  69.    
  70.     #Si no es la primera fila, insertaremos los datos en la nueva base de datos creada.
  71.     else
  72.     {
  73.       #Creamos la sentencia (se sobrecargará cada vez que el for vuelva a recorerse)
  74.       $query = "INSERT INTO tablaPrueba (".$columnes.") VALUES (";
  75.       #Entramos encada una de las líneas con todos los datos.
  76.       for (my $i = 0; $i < @{$lineas[$j]}; $i++ ) {
  77.        
  78.         #Vamos rellenando la sentencia $query con las variables a rellenar extraídas del fichero.
  79.         #En caso de que sea - pondremos un NULL
  80.         #En caso de no serlo, ponemos la variable adecuada
  81.         if($lineas[$j][$i] eq '-') {
  82.           $query = $query.'NULL';
  83.         }
  84.         else
  85.         {
  86.           $query = $query.'"'.$lineas[$j][$i].'"';
  87.         }
  88.        
  89.         #Si no es la última posición, escribimos una , para juntar elementos
  90.         if ($i != @{$lineas[$j]}-1) {
  91.           $query = $query.",";
  92.         }
  93.       }
  94.      
  95.       #Terminamos la sentencia
  96.       $query = $query.")";
  97.      
  98.       #Ejecutamos la sentancia
  99.       $sth = $dbh->prepare($query);
  100.       $sth->execute();
  101.       print "$query <br>";
  102.     }
  103.  
  104. }
  105.  
  106. #Código html
  107. print "</body>\n";
  108. print "</html>\n";
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4


Y una de las líneas problemáticas:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
1388,391,227,AS,NoAS,1,0,68,14,-,-,-,-,-,-,-,-,-,-,-,-,45.8,hsaRAS,-,-,-,-,-,-,SX,SX,-,-,-,-,-,-,-,-,-,-,-,-,2,1,3,3,2
,1,-,-,-,-,-,-
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

que en la tabla me sale:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
1388,391,227,AS,NoAS,1,0,68,14,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,45.8,hsaRAS,NULL,NULL,NULL,
NULL,NULL,NULL,SX,SX,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,2,1,3,3,2,1,NULL,NULL,NULL,NULL,NULL,-
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


¿Alguna sugerencia, para solucionar esto que no sea un UPDATE de todas las filas?

Gracias. :)
Última edición por zangre el 2010-06-23 02:34 @149, editado 1 vez en total
Avatar de Usuario
zangre
Perlero nuevo
Perlero nuevo
 
Mensajes: 36
Registrado: 2010-06-16 06:35 @316
Ubicación: Barcelona

Publicidad

Re: Leer el último elemento de una frase del fichero

Notapor zangre » 2010-06-22 06:12 @300

Bueno, he solucionado por el momento poniendo esto en la línea 94.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     $query =~ s/-/NULL/;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


No se me había ocurrido. :lol:
Pero tampoco sirve porque algunos "-" pasan de mí y se mantienen en su posición.
Avatar de Usuario
zangre
Perlero nuevo
Perlero nuevo
 
Mensajes: 36
Registrado: 2010-06-16 06:35 @316
Ubicación: Barcelona

Re: Leer el último elemento de una frase del fichero

Notapor zangre » 2010-06-22 06:31 @313

Yo me lo guiso y yo me lo como, como juan palomo. xD

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     $query =~ s/-/NULL/g;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Por lo visto en el fichero tengo unos cuantos elementos con valor negativo, que están dando problemas. ;)
Avatar de Usuario
zangre
Perlero nuevo
Perlero nuevo
 
Mensajes: 36
Registrado: 2010-06-16 06:35 @316
Ubicación: Barcelona

Re: Leer el último elemento de una frase del fichero

Notapor zangre » 2010-06-22 07:03 @335

Vale, por lo visto, aunque no se viera, el salto de línea era el que hacía que no reconociera los guiones finales, por lo tanto, en la parte inicial, he modificado la expresión regular que separaba en un array por comas, junto a separarlas por saltos de línea y solucionado. :)

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. # Separo el texto, en los diferentes elementos (separados con comas)
  2. my @lineas;
  3. foreach ( @texto ) {
  4.     push @lineas, [ split /[,\n ]/];
  5. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Avatar de Usuario
zangre
Perlero nuevo
Perlero nuevo
 
Mensajes: 36
Registrado: 2010-06-16 06:35 @316
Ubicación: Barcelona

Re: Leer el último elemento de una frase del fichero

Notapor explorer » 2010-06-22 07:45 @364

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. chomp @texto;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Con esto, es más que suficiente. Se encargará de quitar los caracteres de finales de línea de todos los elementos.

El resto, dejarlo como estaba antes de "arreglarlo" :)

En cuanto al resto del programa, me parece un poco excesivo para el trabajo que hace, que es tratar una línea, que, ya de partida, ya tiene los elementos separados con comas, y lo que tenemos que hacer es poner comillas dobles y transformar los '-' en NULL.

Un ejemplo de cómo se puede hacer:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $texto = '1388,391,1,0,68,14,-,-,-,-,-,45.8,hsaRAS,-,SX,-,-,-,2,1,-,-';

$texto =~ s/,/","/g;     # ponemos comillas a cada coma

$texto = "\"$texto\"";   # ponemos las comillas primera y última

$texto =~ s/"-"/NULL/g;  # sustituimos los '-' por NULL

print "$texto\n";
__END__
"1388","391","1","0","68","14",NULL,NULL,NULL,NULL,NULL,"45.8","hsaRAS",NULL,"SX",NULL,NULL,NULL,"2","1",NULL,NULL
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Sí, es un truco, pero si sabemos que los datos entrantes nunca van a venir con comillas dobles, podemos hacer esta transformación en un par de sentencias.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Leer el último elemento de una frase del fichero

Notapor zangre » 2010-06-23 02:17 @137

explorer escribiste:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. chomp @texto;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Con esto, es más que suficiente. Se encargará de quitar los caracteres de finales de línea de todos los elementos.


JAJAJAJA, ya sabía yo que la estaba liando muy parda. Pensaba que el chomp(), sólo eliminaba el último salto de línea, no todos. Por eso no lo usé. :)

explorer escribiste:En cuanto al resto del programa, me parece un poco excesivo para el trabajo que hace, que es tratar una línea, que, ya de partida, ya tiene los elementos separados con comas, y lo que tenemos que hacer es poner comillas dobles y transformar los '-' en NULL.

Un ejemplo de cómo se puede hacer:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $texto = '1388,391,1,0,68,14,-,-,-,-,-,45.8,hsaRAS,-,SX,-,-,-,2,1,-,-';

$texto =~ s/,/","/g;     # ponemos comillas a cada coma

$texto = "\"$texto\"";   # ponemos las comillas primera y última

$texto =~ s/"-"/NULL/g;  # sustituimos los '-' por NULL

print "$texto\n";
__END__
"1388","391","1","0","68","14",NULL,NULL,NULL,NULL,NULL,"45.8","hsaRAS",NULL,"SX",NULL,NULL,NULL,"2","1",NULL,NULL
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Sí, es un truco, pero si sabemos que los datos entrantes nunca van a venir con comillas dobles, podemos hacer esta transformación en un par de sentencias.


Vale, me gusta la idea, el problema es que el fichero contiene en la primera fila los nombres de las columnas y luego en cada una de las siguientes filas, una fila a rellenar en la base de datos, quiero decir, que no es sólo una fila, sino estamos hablando de unas 20.000 filas, las cuales tengo que mantener separadas al menos por los saltos de línea y en la primera he de separar las comas porque necesito el nombre de las columnas.

Bueno, vamos que voy a aprovechar lo que me has dicho, pero parte de mi código se quedará igual porque no veo otra alternativa. :)

Ej del texto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
var1,var2,var3,var4,var5,var6,var7, ... ,var22
1388,332,1,0,68,14,-,-,-,-,-,45.8,hsaRAS,-,SX,-,-,-,2,1,-,-
1368,3651,1,0,68,14,-,-,-,-,-,45.8,hsaRAS,-,SX,-,-,-,2,1,-,-
1328,651,1,0,68,14,-,-,-,-,-,45.8,hsaRAS,-,SX,-,-,-,2,1,-,-
1388,851,1,0,68,14,-,-,-,-,-,45.8,hsaRAS,-,SX,-,-,-,2,1,-,-
1386,391,1,0,68,14,-,-,-,-,-,45.8,hsaRAS,-,SX,-,-,-,2,1,-,-
1338,399,1,0,68,14,-,-,-,-,-,45.8,hsaRAS,-,SX,-,-,-,2,1,-,-
1308,397,1,0,68,14,-,-,-,-,-,45.8,hsaRAS,-,SX,-,-,-,2,1,-,-
1288,791,1,0,68,14,-,-,-,-,-,45.8,hsaRAS,-,SX,-,-,-,2,1,-,-
1358,391,1,0,68,14,-,-,-,-,-,45.8,hsaRAS,-,SX,-,-,-,2,1,-,-
1398,315,1,0,68,14,-,-,-,-,-,45.8,hsaRAS,-,SX,-,-,-,2,1,-,-
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Sintáxis: [ Descargar ] [ Ocultar ]
Using sql Syntax Highlighting
CREATE TABLE tablaPrueba (var1 VARCHAR(20),var2 VARCHAR(20),var3 VARCHAR(20),var4 VARCHAR(20),var5 VARCHAR(20),
var6 VARCHAR(20),var7 VARCHAR(20), ... ,var22 VARCHAR(20));
INSERT INTO tablaPrueba (var1,var2,var3,var4,var5,var6,var7, ... ,var22) VALUES ("1388", ... , NULL);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Más adelante tendré que hacer algo para detectar si las variables pasadas son enteros, reales o texto. Pero poco a poco. :lol:

Muchas gracias. ;)
Avatar de Usuario
zangre
Perlero nuevo
Perlero nuevo
 
Mensajes: 36
Registrado: 2010-06-16 06:35 @316
Ubicación: Barcelona

Re: Leer el último elemento de una frase del fichero

Notapor explorer » 2010-06-23 06:51 @327

Pues entonces, como la entrada de datos es sencilla, el programa también lo es.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. my $TABLA = 'tablaPrueba';
  7. my $cabecera;
  8.  
  9. open my $FICHERO, q[<], 'kk.txt'  or  die "ERROR: No puedo abrir: $!\n";
  10. open my $SALIDA,  q[>], 'kk1.txt' or  die "ERROR: No puedo escribir: $!\n";
  11.  
  12. while (my $linea = <$FICHERO>) {
  13.     chomp $linea;
  14.  
  15.     if (1 .. 1) {                   # si es la primera línea ...
  16.         $cabecera = $linea;         # es la cabecera
  17.  
  18.         $linea = "DROP   TABLE $TABLA;\n"
  19.                . "CREATE TABLE $TABLA "
  20.                . '('
  21.                .    join( q[,],                         # unidos con comas
  22.                         map { "$_ VARCHAR(20) NULL" }   # los campos formateados
  23.                         split q[,], $cabecera           # extraídos desde la cabecera
  24.                     )
  25.                . ');'
  26.                ;
  27.     }
  28.     else {                          # el resto de las líneas son datos
  29.         $linea =~ s/,/","/g;            # entrecomillamos todos los datos
  30.         $linea = qq("$linea");
  31.  
  32.         $linea =~ s/"-"/NULL/g;         # ajuste para los valores nulos
  33.         $linea =~ s/"([\d.]+)"/$1/g;    # ajuste para números
  34.  
  35.         $linea = "INSERT INTO $TABLA ($cabecera) VALUES ($linea);";
  36.     }
  37.  
  38.     print $SALIDA "$linea\n";
  39. }
  40.  
  41. close   $FICHERO;
  42. close   $SALIDA;
  43.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
DROP   TABLE tablaPrueba;
CREATE TABLE tablaPrueba (var1 VARCHAR(20) NULL,var2 VARCHAR(20) NULL,var3 VARCHAR(20) NULL,var4 VARCHAR(20) NULL,var5 VARCHAR(20) NULL,var6 VARCHAR(20) NULL,var7 VARCHAR(20) NULL,var22 VARCHAR(20) NULL);
INSERT INTO tablaPrueba (var1,var2,var3,var4,var5,var6,var7,var22) VALUES (1388,332,1,0,68,14,NULL,NULL,NULL,NULL,NULL,45.8,"hsaRAS",NULL,"SX",NULL,NULL,NULL,2,1,NULL,NULL);
INSERT INTO tablaPrueba (var1,var2,var3,var4,var5,var6,var7,var22) VALUES (1368,3651,1,0,68,14,NULL,NULL,NULL,NULL,NULL,45.8,"hsaRAS",NULL,"SX",NULL,NULL,NULL,2,1,NULL,NULL);
INSERT INTO tablaPrueba (var1,var2,var3,var4,var5,var6,var7,var22) VALUES (1328,651,1,0,68,14,NULL,NULL,NULL,NULL,NULL,45.8,"hsaRAS",NULL,"SX",NULL,NULL,NULL,2,1,NULL,NULL);
INSERT INTO tablaPrueba (var1,var2,var3,var4,var5,var6,var7,var22) VALUES (1388,851,1,0,68,14,NULL,NULL,NULL,NULL,NULL,45.8,"hsaRAS",NULL,"SX",NULL,NULL,NULL,2,1,NULL,NULL);
INSERT INTO tablaPrueba (var1,var2,var3,var4,var5,var6,var7,var22) VALUES (1386,391,1,0,68,14,NULL,NULL,NULL,NULL,NULL,45.8,"hsaRAS",NULL,"SX",NULL,NULL,NULL,2,1,NULL,NULL);
INSERT INTO tablaPrueba (var1,var2,var3,var4,var5,var6,var7,var22) VALUES (1338,399,1,0,68,14,NULL,NULL,NULL,NULL,NULL,45.8,"hsaRAS",NULL,"SX",NULL,NULL,NULL,2,1,NULL,NULL);
INSERT INTO tablaPrueba (var1,var2,var3,var4,var5,var6,var7,var22) VALUES (1308,397,1,0,68,14,NULL,NULL,NULL,NULL,NULL,45.8,"hsaRAS",NULL,"SX",NULL,NULL,NULL,2,1,NULL,NULL);
INSERT INTO tablaPrueba (var1,var2,var3,var4,var5,var6,var7,var22) VALUES (1288,791,1,0,68,14,NULL,NULL,NULL,NULL,NULL,45.8,"hsaRAS",NULL,"SX",NULL,NULL,NULL,2,1,NULL,NULL);
INSERT INTO tablaPrueba (var1,var2,var3,var4,var5,var6,var7,var22) VALUES (1358,391,1,0,68,14,NULL,NULL,NULL,NULL,NULL,45.8,"hsaRAS",NULL,"SX",NULL,NULL,NULL,2,1,NULL,NULL);
INSERT INTO tablaPrueba (var1,var2,var3,var4,var5,var6,var7,var22) VALUES (1398,315,1,0,68,14,NULL,NULL,NULL,NULL,NULL,45.8,"hsaRAS",NULL,"SX",NULL,NULL,NULL,2,1,NULL,NULL);
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Seguramente sería deseable un formateo mayor, como por ejemplo, entrecomillar los campos de la cabecera, para estar seguros.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Leer el último elemento de una frase del fichero

Notapor zangre » 2010-06-23 07:05 @337

Joder, ¡leches! De grande quiero ser como tú. :D

Con la que he liado yo con el código. ^^!
Gracias. :)

explorer escribiste:Pues entonces, como la entrada de datos es sencilla, el programa también lo es.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.         print $SALIDA
  2.             join  q[,],
  3.             map   { "$_ VARCHAR(20) NULL" }
  4.             split q[,],
  5.             $cabecera
  6.             ;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Bueno, al lío, esta parte entiendo lo que hace en global pero no acabo de ver bien el proceso, a ver si acierto.

Pintas $SALIDA que es $cabecera convertida en un array, separando por las comas, que le has añadido el VARCHAR(20) NULL, que lo has vuelto a convertir en un "string" añadiendo las comas. ¿Es así?

Es increíble que se pueda hacer todo eso en una sola sentencia. :lol:
Avatar de Usuario
zangre
Perlero nuevo
Perlero nuevo
 
Mensajes: 36
Registrado: 2010-06-16 06:35 @316
Ubicación: Barcelona

Re: Leer el último elemento de una frase del fichero

Notapor explorer » 2010-06-23 08:04 @377

Sí, el trabajo de esa línea es ese, salvo que $SALIDA es el controlador del fichero de salida, donde queda grabado el resultado.

He vuelto a editar el programa (los mensajes se pueden reeditar) para agregar comentarios en esas líneas, aparte de hacerlo más corto (en escritura).

Veo que el problema está en la creación de la tabla, donde no sabemos el tipo de cada campo.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Leer el último elemento de una frase del fichero

Notapor zangre » 2010-06-25 02:19 @138

Eso lo pensaba solucionar, diciéndole a los que quieran crear la tabla que junto al nombre de la columna, pongan separado por una barra o algo así, el tipo de variable que será, y de ahí recogerlo y ponerlo yo en el create table. :)
Avatar de Usuario
zangre
Perlero nuevo
Perlero nuevo
 
Mensajes: 36
Registrado: 2010-06-16 06:35 @316
Ubicación: Barcelona

Siguiente

Volver a Básico

¿Quién está conectado?

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

cron