• Publicidad

Carga de archivo CSV

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

Carga de archivo CSV

Notapor reLlene » 2012-06-17 15:21 @681

Antes que nada, mi saludos a todos en esta gran comunidad a la que hace muy poquito me uní :D

Vamos a ver, me encuentro ante la problemática de correr el programa, de entrada. Mi objetivo es cargar el archivo CSV que adjunto más abajo: este contiene los campos nroDeCte, cteBtc, fechaDeAlta, nomb, estado, IP, MAC y (por último) servicio. Las consultas que quiero hacer a dicho archivo son las siguientes: ¿cuántos servicios distintos tengo? y... ¿cuántos clientes de CADA servicio tengo? (esta no la saco :? )

Les muestro lo que tengo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open( CLIENTES, "< /home/usuarios_cablemodem.csv" ) || die "No puedo abrir el archivo. Error: $!";
  2.  
  3. while (<CLIENTES>) {
  4.     chomp($_);
  5.     my @clientes = split( /\s+/, $clientes )    # while va guardando cada linea leída
  6.  
  7. }
  8. close(CLIENTES);
  9.  
  10. my $clientes_INTERNET       = 0;
  11. my $clientes_MTA            = 0;
  12. my $clientes_solo_telefonia = 0;
  13. my $i                       = 0;
  14.  
  15. for ( $i; $i < $#clientes; $i++ ) {
  16.     $cliente = $clientes[$i]
  17.         if ( $cliente =~ INTERNET ) {
  18.         ++$clientes_internet;
  19.     }
  20.     elsif ( $cliente =~ MTA ) {
  21.         ++$clientes_mta;
  22.     }
  23.     else {
  24.         elsif ( $cliente =~ TELEFONIA )++ $clientes_solo_telefonia;
  25.     }
  26.  
  27.     print "\nCantidad de clientes con 64 = $clientes_internet\n";
  28.     print "Cantidad de clientes con 128 = $clientes_mta\n";
  29.     print "Cantidad de clientes con 128 = $clientes_solo_telefonia\n";
  30.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Numero de cliente;Cliente BTS;Fecha de Alta;Nombre;Estado;IP;MAC;Servicio
19234;2979;2011-08-24;A.S.X.E.M., ;Activo;10.100.115.219;00:1d:cd:db:4a:9d;512/128 Kb (CPE 1) - MTA;
22775;3550;2012-03-27;ABACO, CRISTIAN RAUL;Activo;10.100.117.21;00:1d:cd:ee:a5:c0;512/128 Kb (CPE 1) - MTA;
21307;3278;2011-11-25;ABAL, FABIO GABRIEL;Activo;10.100.119.207;00:02:00:4b:f8:58;256/128 Kb (CPE 1) - INTERNET;
32972;2412;2011-02-19;ABAYAR GONZALO;Activo;10.100.112.250;00:15:d1:41:0a:a5;SOLO TELEFONIA;
363;211;0000-00-00;ABAYAR, GONZALO;Activo;10.100.105.248;00:15:96:de:8b:99;SOLO TELEFONIA;
31590;2969;2011-08-23;ABALOR, DANI WALTER;Activo;10.100.118.148;00:15:d1:5b:4a:17;256/128 Kb (CPE 1) - INTERNET;
18212;231;0000-00-00;ABALOS, RICHARD ALFREDO;Activo;10.100.104.57;00:15:96:de:95:2c;SOLO TELEFONIA;  
35573;3406;2012-02-06;ABEYO MARTINEZ CLAUDIO FIDEL;Activo;10.100.118.129;00:02:00:40:ee:6c;512/128 Kb (CPE 1) - INTERNET;
22914;2356;2011-01-26;HACCINEL, JOSE LUIS;Activo;10.100.105.27;00:15:96:e2:db:b0;SOLO TELEFONIA;
34598;3012;2011-08-29;HACEBEDO IVANA SOLEDAD;Activo;10.100.113.87;00:1d:cd:db:25:d1;SOLO TELEFONIA;
17013;3673;2012-05-10;HACEBEDO, DORA;Activo;10.100.114.142;00:15:a4:62:b4:42;256/128 Kb (CPE 1) - INTERNET;
22695;2905;2011-08-16;HACEBEDO, GASTON DARIO;Activo;10.100.119.75;00:02:00:4b:ed:4c;512/128 Kb (CPE 1) - INTERNET;  
25251;1407;0000-00-00;HACEBEDO, MURIEL ROSALBA;Activo;10.100.114.108;00:15:ce:52:86:4a;SOLO TELEFONIA;
33832;2735;2011-05-24;LACOST RICARDO ARISTOTELES;Activo;10.100.115.5;00:1d:cd:db:4e:de;SOLO TELEFONIA;
35397;3375;2012-01-23;LACOSTA ROQUE DAMIAN;Activo;10.100.117.79;00:02:00:4b:cc:e2;512/128 Kb (CPE 1) - INTERNET;
35716;3517;2012-03-17;LACOSTA VERONICA ALEJANDRA;Activo;10.100.118.200;00:1d:cd:f3:4e:0a;512/128 Kb (CPE 1) - MTA;
18356;282;0000-00-00;LACOSTA, ANDRES HUMBERTO;Activo;10.100.106.123;00:15:96:de:92:7a;SOLO TELEFONIA;
31197;2008;0000-00-00;LACOSTA, DAVID RODOLFO;Activo;10.100.113.61;00:23:be:40:2a:50;SOLO TELEFONIA;
31887;3021;2011-08-30;LACOSTA, HUGO ABEL;Activo;10.100.112.87;00:02:00:4b:f0:30;512/128 Kb (CPE 1) - INTERNET;
31700;3584;2012-04-13;LACOSTA, JULIAN MIGUEL;Activo;10.100.117.109;00:15:a3:1c:0c:c9;2048/512 Kb (CPE 1) - INTERNET;
33265;2580;2011-04-12;LACOSTA, RAMON VICENTE;Activo;10.100.119.146;00:1d:cd:db:4e:93;SOLO TELEFONIA;
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
Última edición por explorer el 2012-06-17 15:58 @707, editado 1 vez en total
Razón: Formateado de código con Perltidy
Sexo : unzip ; strip ; touch ; grep ; finger ;mount ; fsck ; more ; yes ; umount ; sleep.
Avatar de Usuario
reLlene
Perlero nuevo
Perlero nuevo
 
Mensajes: 97
Registrado: 2012-06-04 07:16 @344

Publicidad

Re: Carga de archivo CSV

Notapor explorer » 2012-06-17 16:54 @745

Bienvenido a los foros de Perl en Español, reLlene.

Primero, unas puntualizaciones...
  • No es un archivo CSV... el delimitador no es la coma, sino el punto y coma :)
  • Línea 1: estás intentando abrir el archivo 'usuarios_cablemodem.csv' pero en realidad se llama 'Usuarios_Cablemodem.csv' (atento a las mayúsculas: en Unix/Linux son significativas)
  • Línea 5: estás intentado hacer un split() de la variable $clientes pero... ¿de dónde viene esa variable? ¿No será que quieres partir $_ que contiene la línea que acabas de leer en la línea 3?
  • Línea 5 (otra vez): estás dividiendo por /\s+/ (espacios en blanco), pero el separador... es el carácter ';', ¿no?
  • Línea 5 (sí, otra): el resultado de la división lo estás guardando en la variable local @clientes... pero en cuanto termine el bucle (línea 7), esa variable desaparecerá
  • Línea 13: casi mejor meterla en la primera expresión del for() de la línea 15
  • Línea 15: si haces la comparación hasta $#clientes, no estarás leyendo el último elemento de @clientes
  • Línea 16: falta un ';' al final
  • Línea 17: faltan los delimitadores '/.../' alrededor de 'INTERNET'
  • Línea 17: ¿sabes que $cliente contiene toda la línea del archivo? ¿No será que solo quieres ver si está INTERNET en el campo Servicio? Porque... ¿qué pasaría si un usuario -muy malo- dijese que su nombre es, precisamente, 'INTERNET'?
  • Línea 18: ¿de dónde sale la variable $clientes_internet? ¿No será $clientes_INTERNET?
  • Línea 20: mismo comentario que la 17
  • Línea 21: mismo comentario que la 18
  • Línea 23: sobra
  • Línea 24: mismo comentario que la 17
  • Línea 24: faltan la llave de apertura de bloque
  • Línea 27: mismo comentario que la 18
  • Línea 28: mismo comentario que la 21
Bueno, una versión más remozada sería esta:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. open(CLIENTES, "< /home/Usuarios_Cablemodem.csv" )    # abrimos
  7.     || die "No puedo abrir el archivo. Error: $!";
  8. my @clientes = <CLIENTES>;                            # leemos
  9. close(CLIENTES);                                      # cerramos
  10. chomp(@clientes);                                     # le quitamos el final
  11.  
  12. my $clientes_INTERNET       = 0;
  13. my $clientes_MTA            = 0;
  14. my $clientes_solo_telefonia = 0;
  15.  
  16. for (my $i = 0; $i < @clientes; $i++ ) {              # para todos los clientes
  17.                                                       # partimos la línea
  18.     my($numero, $BTS, $alta, $nombre, $estado, $IP, $MAC, $servicio) = split(/;/, $clientes[$i]);
  19.  
  20.     if ( $servicio =~ m/INTERNET/ ) {                 # si el servicio contiene 'INTERNET'
  21.         $clientes_INTERNET++;
  22.     }
  23.     elsif ( $servicio =~ m/MTA/ ) {                   # si el servicio contiene 'MTA'
  24.         $clientes_MTA++;
  25.     }
  26.     elsif ( $servicio eq 'SOLO TELEFONIA' ) {         # si el servicio es 'SOLO TELEFONIA'
  27.         $clientes_solo_telefonia++;
  28.     }
  29. }
  30.  
  31. print "\n";
  32. print "Cantidad de clientes con 64  = $clientes_INTERNET\n";
  33. print "Cantidad de clientes con 128 = $clientes_MTA\n";
  34. print "Cantidad de clientes con 128 = $clientes_solo_telefonia\n";
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Ahora bien... esto no responde a lo que se pregunta... lo que estamos buscando es cuántos servicios distintos hay, y cuántos clientes hay por cada servicio.

Podríamos ir buscando servicio por servicio y colocar una rama if() más... pero tendríamos que ir cambiando el programa cada vez que la situación cambiara (nuevos servicios). La solución no es robusta...

Gracias al poder de los hash de Perl, se puede resolver fácilmente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use feature 'say';                      # función say()
  3. use autodie;                            # «Mejor morir que regresar con deshonor» --Proverbio Kinglon
  4.  
  5. my %estadisticas;
  6.  
  7. open my $CSV, q[<], 'Usuarios_Cablemodem.csv';
  8.  
  9. readline $CSV;                                  # nos saltamos la línea de cabecera
  10.  
  11. while (readline $CSV) {
  12.  
  13.     my $servicio = ( split /;/ ) [ 7 ];         # el $servicio es la columna número 7
  14.  
  15.     $estadisticas{ $servicio }++;               # sumamos un usuario más del $servicio
  16. }
  17.  
  18. close $CSV;
  19.  
  20. while(my($servicio, $usuarios) = each %estadisticas) {          # para cada $servicio encontrado
  21.     say join "\t", $servicio, '=>', $usuarios;
  22. }
  23.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
sale:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
1024/512 Kb (CPE 1) - INTERNET  =>      5
1024/256 Kb (CPE 1) - MTA       =>      9
256/128 Kb (CPE 1) - INTERNET   =>      45
2048/512 Kb (CPE 1) - MTA       =>      9
512/128 Kb (CPE 1) - INTERNET   =>      330
2048/512 Kb (CPE 1) - INTERNET  =>      1
256/128 Kb (CPE 1) - MTA        =>      48
NO ACCESS       =>      8
128/64 Kb (CPE 1) - INTERNET    =>      2
SOLO TELEFONIA  =>      1598
512/128 Kb (CPE 1) - MTA        =>      348
2048/1024 Kb (CPE 1) - MTA      =>      3
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: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Carga de archivo CSV

Notapor reLlene » 2012-06-17 19:40 @861

explorer, muchas gracias por la mano... Ahora, por cierto, ¿por qué dices que no se trata de un archivo .cs Es decir, ahora comprendo del error que cometía al usar el delimitador /\s+/ en lugar del “;” (como se encuentran separados los datos del archivo) pero no me entero por qué deja de ser un CSV. Bueno, al menos esa es la extensión, ¿no? :?

Otras dudas que tengo son:

- ¿Por qué el cambio rotundo del uso de funciones? Me refiero, no has vuelto a usar las mismas que las del primer programa

- Esta línea:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open my $CSV, q[<], 'Usuarios_Cablemodem.csv';
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
¿puede escribirse de esta otra forma, también?
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $CSV
  2. OPEN($CSV,< Usuarios_Cablemodem.csv” ); # abro simplemente el archivo para luego hacer la consulta
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


- y con esta otra:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     $estadisticas{ $servicio }++;               # sumamos un usuario más del $servicio
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
¿Lo que quieres decir es que aumenta en 1 el contador clientes, cada vez que lee un servicio distinto?

También probe corriendo el programa desde la terminal y me arroja error a la hora de leer el archivo, intui que se debia a los permisos y tal pero es que los modificado y aun persiste el error, a qué puede deberse?? :?
Perdón por la ignorancia, es que trato de interpretar la "esencia" del programa para así poder comprenderlo.
Sexo : unzip ; strip ; touch ; grep ; finger ;mount ; fsck ; more ; yes ; umount ; sleep.
Avatar de Usuario
reLlene
Perlero nuevo
Perlero nuevo
 
Mensajes: 97
Registrado: 2012-06-04 07:16 @344

Re: Carga de archivo CSV

Notapor explorer » 2012-06-17 20:25 @892

reLlene escribiste:¿por qué dices que no se trata de un archivo .cs Es decir, ahora comprendo del error que cometía al usar el delimitador /\s+/ en lugar del “;” (como se encuentran separados los datos del archivo) pero no me entero por qué deja de ser un CSV. Bueno, al menos esa es la extensión, ¿no? :S
Sí... pero hay que aclarar que originalmente el formato CSV se reservaba para los archivos que tenían como delimitadores solo a las comas. Más adelante se puso el punto y coma en aquellos lugares donde usamos la coma para otras cosas (más información en la página CSV de Wikipedia).

reLlene escribiste:¿Por qué el cambio rotundo del uso de funciones? Me refiero, no has vuelto a usar las mismas que las del primer programa
Pues... porque así hay que escribir menos, o porque quizás queda más claro. Cierto es que hay que escribir más poniendo "readline $CSV" que "<$CSV>", pero queda más claro que estamos leyendo una línea.

reLlene escribiste:Esta línea:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open my $CSV, q[<], 'Usuarios_Cablemodem.csv';
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
¿puede escribirse de esta otra forma, también?
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $CSV
  2. OPEN($CSV,< Usuarios_Cablemodem.csv” ); # abro simplemente el archivo para luego hacer la consulta
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Sí, es lo mismo, pero lo recomendable estos días es siempre usar la forma de open() de tres argumentos.

reLlene escribiste:y con esta otra:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     $estadisticas{ $servicio }++;               # sumamos un usuario más del $servicio
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
¿Lo que quieres decir es que aumenta en 1 el contador clientes, cada vez que lee un servicio distinto?
Aumento en uno las veces que ha aparecido $servicio.

Imagínate que tienes que hacer este problema con lápiz y papel.
Lees la primera línea del archivo.
Te fijas en la columna servicio.
Vas al papel (que está en blanco), y escribes el nombre del servicio y un '1' debajo.
Lees la siguiente línea y sacas otro servicio.
Si coincide con el que tenías antes, cambias el '1' por un '2', pero si no coincide, creas una nueva columna para ese nuevo servicio, y '1' debajo.
Y así para todas las líneas: vas creando columnas de servicios y aumentando los contadores.

Al final, tienes tantas columnas como servicios distintos, y debajo de cada una, las veces que ha aparecido.

El hash funciona así.
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: Carga de archivo CSV

Notapor reLlene » 2012-06-17 21:13 @925

Una vez más, gracias, explorer, ¡¡¡ por la mano que me vienes dando y lo claro que te explicas !!!

Ahora... ¿sabes por qué puede arrojarme la terminal el error a la hora de leer el archivo csv del script? Me dice que el archivo o directorio no existe en esa ubicación y me he asegurado del case sensitive (como me has dicho) a la hora del llamado del mismo y tanto con comillas simples como las dobles. Trabajo con Ubuntu :?
Sexo : unzip ; strip ; touch ; grep ; finger ;mount ; fsck ; more ; yes ; umount ; sleep.
Avatar de Usuario
reLlene
Perlero nuevo
Perlero nuevo
 
Mensajes: 97
Registrado: 2012-06-04 07:16 @344

Re: Carga de archivo CSV

Notapor explorer » 2012-06-18 07:46 @365

No es lo mismo ninguna de estas líneas:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open my $CSV, q[<], 'Usuarios_Cablemodem.csv';
  2. open my $CSV, q[<], 'usuarios_cablemodem.csv';
  3. open my $CSV, q[<], '/home/Usuarios_Cablemodem.csv';
  4. open my $CSV, q[<], '/home/usuarios_cablemodem.csv';
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Las dos primeras buscan el archivo en el mismo directorio donde se está ejecutando el programa.

Las dos últimas sí que buscan los archivos dentro del '/home/'.

Y a su vez, los nombres de los archivos según el tamaño de caja de las letras.

Una forma de estar seguro es ejecutar en la línea de comandos el comando ls -l junto con lo que está entre las comillas. Por ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
  1. ls -l /home/Usuarios_Cablemodem.csv
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Así sabrás si la ruta y/o el nombre del archivo es correcto.
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 19 invitados