• Publicidad

Leer un txt delimitado por coma

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

Leer un txt delimitado por coma

Notapor coltx » 2016-08-08 16:25 @726

Estimados, tengo el siguiente script que lee información desde un archivo txt en el cual sus campos están separados por comas, pero hay campos que vienen encerrados en comillas ya que en el valor del campo vienen comas, entonces el script cuando lee el campo lo divide siendo que no debiera ser, ¿qué puedo hacer?

Mi script es el siguiente:

#!/usr/bin/perl
open (FILE, @ARGV[0]) || die "No pude abrir el archivo @ARGV[0]\n";

$NFile="@ARGV[0]";


foreach $a (<FILE>)
{

### separo los campos y asigno a variables ###

@datos=split(/\,/,$a);
my $Nombre = @datos[0];
my $Apellido = @datos[1];
my $Empresa = @datos[2];
}

El archivo txt viene de la siguiente manera:

Cristian,olivar,telecom
Pablo,olguin,salfast
Ignacio,Herrera,"solución,Ricoh.ltda"

Para en la línea 3 el script erróneamente lee lo siguiente:
Ignacio
Herrera
"solucion

Lo correcto debería ser:
Ignacio
Herrera
solución,Ricoh.ltda

Gracias por su ayuda.
coltx
Perlero nuevo
Perlero nuevo
 
Mensajes: 79
Registrado: 2011-09-16 08:01 @376

Publicidad

Re: Leer un txt delimitado por coma

Notapor explorer » 2016-08-08 17:37 @775

Podías intentarlo con una expresión regular muy complicada, pero lo mejor y más cómodo es usar Text::CSV. Y si luego ves que funciona y va bien, instalar Text::CSV_XS, que es la versión compilada en C, para hacerlo a máxima velocidad (y sin tener que cambiar nada en el programa tuyo).

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use Text::CSV;
  2.  
  3. my $csv = Text::CSV->new ();
  4.  
  5. open my $io, "<", $file or die "$file: $!";
  6.  
  7. while (my $fila = $csv->getline ($io)) {
  8.     my @campos = @$fila;
  9.     # aquí ya tenemos los @campos de la $fila
  10. }
Coloreado en 0.002 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: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Leer un txt delimitado por coma

Notapor coltx » 2016-08-11 08:43 @404

Me pasa exactamente los mismo, en vez de generar un campo me genera 3 campos, ya que encuentra el delimitador coma entremedio de las comillas:

Cristian,olivar,telecom
Pablo,olguin,salfast
Ignacio,Herrera,"solución,Ricoh.ltda"

Me genera para la última línea :

Ignacio
Herrera
"solución
ricoh.
ltda

y lo correcto debería ser:

Ignacio
Herrera
solución,Ricoh.ltda
coltx
Perlero nuevo
Perlero nuevo
 
Mensajes: 79
Registrado: 2011-09-16 08:01 @376

Re: Leer un txt delimitado por coma

Notapor explorer » 2016-08-11 12:59 @582

Hola. A mi me funciona perfectamente. Lo único que he tenido que agregarle es un use open ':locale', ya que mis datos están codificados en utf8:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2. use autodie;
  3. use open IO => ':locale';
  4. use Text::CSV; # Text::CSV_PP
  5.  
  6. my $csv = Text::CSV->new ({
  7. #       eol             => $/,          # final de línea
  8. #       binary          => 1,           # tratamiento binario de los campos
  9. #       decode_utf8     => 1,           # los campos están en utf8
  10. #       quote_binary    => 1,           # los campos con datos binarios están entrecomillados
  11. #       auto_diag       => 1,           # avisa de errores
  12. });
  13.  
  14. open my $io, '<', 'kk.txt';
  15.  
  16. while (my $fila = $csv->getline ($io)) {
  17.  
  18. #    print $csv->string(), "\n";        # no funciona con Text::CSV_XS
  19.  
  20.     my @campos = @$fila;
  21.  
  22.     # aquí ya tenemos los @campos de la $fila
  23.  
  24.     print join("|", @campos), "\n";
  25. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Entonces, a partir del archivo
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Cristián,olivar,telecom
Pablo,olguin,salfast
Ignacio,Herrera,"solución,Ricoh.ltda"
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
tenemos esta salida:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Cristián|olivar|telecom
Pablo|olguin|salfast
Ignacio|Herrera|solución,Ricoh.ltda
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Y me funciona tanto con Text::CSV como con Text::CSV_XS.

El tema de la codificación es importante: si el módulo detecta un byte que el considera que es binario, y ese campo no está entrecomillado, sacará este error (si está activada la opción auto_diag):

# CSV_XS ERROR: 2037 - EIF - Binary character in unquoted field, binary off

Podemos evitar ese caso (por ejemplo, 'Cristián', en el primer registro) añadiendo quote_binary => 0, por lo que admitirá esos casos.

Según tus datos estén en otras codificaciones, es posible que tengas que activar la opción binary=>1 (según el manual, muy recomendable).

Esta es otra combinación que funciona, sin usar 'open locale':
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2. use autodie;
  3. use Text::CSV;
  4.  
  5. my $csv = Text::CSV->new ({
  6.         eol             => $/,          # final de línea
  7.         binary          => 1,           # tratamiento binario de los campos
  8.         decode_utf8     => 1,           # los campos están en utf8
  9.         quote_binary    => 0,           # los campos con datos binarios están entrecomilladas
  10.         auto_diag       => 1,           # avisa de errores
  11. });
  12.  
  13. binmode(STDOUT, ':utf8');               # la salida del print -nuestra terminal- será en utf8
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

En fin, jugando con los parámetros del new(), es posible indicar cómo son los datos que estamos tratando. Pero lo principal, en el primer ejemplo, es que veas que con los valores por defecto, el módulo nos resuelve el problema.
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


Volver a Básico

¿Quién está conectado?

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

cron