• 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.

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

Notapor zangre » 2010-06-25 04:20 @222

Una cosita, he estado mirando, porque la intención final es que usen el script con .csv que en lugar de comas usa punto y coma, pero veo que los saltos de línea se los pasa por el forro. ¿Hay alguna forma de detectar cuándo salta de una línea a otra?

Veo que en el resto del foro, todos los ejemplos que hay ninguno pone nada especial para esto, pero me extraña, he puesto como ejemplo una tabla de 4x4 elementos, y me los pone todos en el create table, sin respetar que 3 filas deberían ir como INSERT. :/
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 explorer » 2010-06-25 05:03 @252

Perl usa el valor de $/ ($INPUT_RECORD_SEPARATOR) para saber dónde termina cada registro que va leyendo. Como por defecto es el avance de línea / retorno de carro (según el sistema operativo), entonces no hay que hacer ni indicar nada para leer los ficheros de texto.

Si pones un ejemplo de entrada y el código que estás probando te podremos decir qué es lo que falla.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

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

Notapor marcmb » 2010-06-27 17:08 @755

¿No puede ser que tengan doble retorno de línea, es decir "\n\n"?
Es que a mi me ha pasado este problema y tardé en darme cuenta :P
Avatar de Usuario
marcmb
Perlero nuevo
Perlero nuevo
 
Mensajes: 55
Registrado: 2010-05-03 07:42 @362
Ubicación: Girona

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

Notapor zangre » 2010-06-28 01:52 @119

Hola, perdonad que no haya contestado antes, es que me he tomado el puente muy en serio. :lol:
Explorer, el código que usé fue el tuyo (el último que pusiste), sólo que añadiendo en la linea 13(justo debajo del while y antes del chomp):
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $linea =~ s/;/,/g;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Código completo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/Applications/XAMPP/xamppfiles/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[<], 'Libro1.csv'  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.     $linea =~ s/;/,/g;
  14.     chomp $linea;
  15.  
  16.     if (1 .. 1) {                   # si es la primera línea ...
  17.         $cabecera = $linea;         # es la cabecera
  18.  
  19.         $linea = "DROP   TABLE $TABLA;\n"
  20.                . "CREATE TABLE $TABLA "
  21.                . '('
  22.                .    join( q[,],                         # unidos con comas
  23.                         map { "$_ VARCHAR(20) NULL" }   # los campos formateados
  24.                         split q[,], $cabecera           # extraídos desde la cabecera
  25.                     )
  26.                . ');'
  27.                ;
  28.     }
  29.     else {                          # el resto de las líneas son datos
  30.         $linea =~ s/,/","/g;            # entrecomillamos todos los datos
  31.         $linea = qq("$linea");
  32.  
  33.         $linea =~ s/"-"/NULL/g;         # ajuste para los valores nulos
  34.         $linea =~ s/"([\d.]+)"/$1/g;    # ajuste para números
  35.  
  36.         $linea = "INSERT INTO $TABLA ($cabecera) VALUES ($linea);";
  37.     }
  38.  
  39.     print $SALIDA "$linea\n";
  40. }
  41.  
  42. close   $FICHERO;
  43. close   $SALIDA;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


El resto era exactamente el mismo, y en el fichero me salió todo en el create table y no en el insert:
Fichero.csv
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
1;2;3;4
1;2;3;4
5;6;7;8
9;10;11;12
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Tabla que crea:
Sintáxis: [ Descargar ] [ Ocultar ]
Using sql Syntax Highlighting
  1. DROP   TABLE tablaPrueba;
  2. CREATE TABLE tablaPrueba (1 VARCHAR(20) NULL,2 VARCHAR(20) NULL,3 VARCHAR(20) NULL,4
  3. 1 VARCHAR(20) NULL,2 VARCHAR(20) NULL,3 VARCHAR(20) NULL,4
  4. 5 VARCHAR(20) NULL,6 VARCHAR(20) NULL,7 VARCHAR(20) NULL,8
  5. 9 VARCHAR(20) NULL,10 VARCHAR(20) NULL,11 VARCHAR(20) NULL,12 VARCHAR(20) NULL);
  6.  
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-28 04:18 @221

Esto es lo que me sale a mí, al ejecutar tu código:
Sintáxis: [ Descargar ] [ Ocultar ]
Using sql Syntax Highlighting
  1. DROP   TABLE tablaPrueba;
  2. CREATE TABLE tablaPrueba (1 VARCHAR(20) NULL,2 VARCHAR(20) NULL,3 VARCHAR(20) NULL,4 VARCHAR(20) NULL);
  3. INSERT INTO tablaPrueba (1,2,3,4) VALUES (1,2,3,4);
  4. INSERT INTO tablaPrueba (1,2,3,4) VALUES (5,6,7,8);
  5. INSERT INTO tablaPrueba (1,2,3,4) VALUES (9,10,11,12);
Coloreado en 0.000 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: 14482
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-28 06:03 @294

Vale, esto sí que es raro de narices.
Seguro que la culpa la tiene el Microsoft Excel para MacOSX :lol:

Afirmativo, la culpa es del Excel, ahora he copiado el texto y lo he guardado en otro .csv y mira, funciona, pero es un poco preocupante, ¿no? Porque si cada vez que quieran cargar el fichero han de abrirlo en un gedit o similar, para copiar y pegar... no es plan.
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-28 07:26 @352

Si el csv está generado en MacOS, es posible que tenga los finales de línea a CR (al estilo de Mac).

Y si el programa Perl lo estás ejecutando en Windows, los finales de línea son otros (LN+CR) o si lo haces en Linux o UNIX, otro distinto (LN).

Perl, en Windows, intentará pasar los finales de línea en LN del antiguo DOS al nuevo CRLF, pero si le estás pasando otro formato distinto, pues se hará un lío.

Entonces, debes mirar cuál son los finales de línea que Excel te ha dejado, porque así deberás ayudar en la lectura de las líneas (<>) y el chomp().

Esto lo resuelves ajustando la variable especial $/.

Más información en perlport, sección Newlines.

Mira a ver si puedes ver el contenido del fichero, byte a byte, con un editor hexadecimal, por ejemplo, y así sabrás si lo escribe bien o no.

En Linux, yo uso hexdump:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
explorer@joaquin:~/Documents/Desarrollo> hexdump -C Libro1.csv
00000000  31 3b 32 3b 33 3b 34 0a  31 3b 32 3b 33 3b 34 0a  |1;2;3;4.1;2;3;4.|
00000010  35 3b 36 3b 37 3b 38 0a  39 3b 31 30 3b 31 31 3b  |5;6;7;8.9;10;11;|
00000020  31 32 0a                                          |12.|
00000023
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

O también desde el propio Perl:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
~> perl -le 'my $f = join "", <>; print join " ", map { unpack "H*", $_  } split //, $f' Libro1.csv
31 3b 32 3b 33 3b 34 0a 31 3b 32 3b 33 3b 34 0a 35 3b 36 3b 37 3b 38 0a 39 3b 31 30 3b 31 31 3b 31 32 0a
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Se ve claramente que los finales de línea yo los tengo en formato UNIX (0x0a es el avance de línea).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
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-29 02:21 @140

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
mac-2:Documents miau$ hexdump -C Libro2.csv
00000000  31 3b 32 3b 33 3b 34 0d  38 3b 37 3b 36 3b 35 0d  |1;2;3;4.8;7;6;5.|
00000010  39 3b 31 30 3b 31 31 3b  31 32 0d 31 36 3b 31 35  |9;10;11;12.16;15|
00000020  3b 31 34 3b 31 33                                 |;14;13|
00000026
 
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
  1. mac-2:Documents miau$ perl -le 'my $f = join "", <>; print join " ", map { unpack "H*", $_  } split //, $f' Libro2.csv
  2. 31 3b 32 3b 33 3b 34 0d 38 3b 37 3b 36 3b 35 0d 39 3b 31 30 3b 31 31 3b 31 32 0d 31 36 3b 31 35 3b 31 34 3b 31 33
  3.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Ahí está la diferencia, en Mac se usa el 0x0d en lugar del 0x0a.
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-29 03:23 @182

El valor de 0x0d es el 13 decimal (\015 en octal), así que es el carácter "\r", lo cual es correcto, porque se trata del sistema operativo MacOS.

Pero si ejecutas el programa Perl, en el mismo sistema MacOS, no deberías tener ningún problema, ya que Perl trataría "\n" como ese final de línea. Y chomp() sabría qué quitar, etc...

Con el siguiente código se demuestra que Perl es capaz de leer por líneas. Fíjate que como no hay chomp(), se mantiene el final de línea y por eso el corchete de cierre está una línea más abajo.
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
> perl -le 'print join "\n", map { "[$_]" } <>' Libro1.csv
[1;2;3;4
]
[1;2;3;4
]
[5;6;7;8
]
[9;10;11;12
]
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Lo que me llama la atención es que le falta un final de línea en la última línea. Pero bueno, si usamos chomp(), no pasa nada.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
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-29 07:55 @372

Pues ahí está la gracia del asunto, porque lo compilo y lo ejecuto en el Mac, y dice que nanai, que los saltos de linea para ti porque él no lo quiere.

He ejecutado en el terminal tu sentencia y mira qué curioso:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
mac-2:htdocs miau$ perl -le 'print join "\n", map { "[$_]" } <>' Libro2.csv
16;15;14;13]
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Me encantaría saber qué diablos está haciendo el Excel, a parte de llevarme la contraria. :lol:
Avatar de Usuario
zangre
Perlero nuevo
Perlero nuevo
 
Mensajes: 36
Registrado: 2010-06-16 06:35 @316
Ubicación: Barcelona

AnteriorSiguiente

Volver a Básico

¿Quién está conectado?

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