• Publicidad

Leer y reemplazar cadena de texto

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

Leer y reemplazar cadena de texto

Notapor bvayap » 2013-05-31 05:31 @271

Hola,

Soy nuevo en Perl y también en este foro (aunque me está gustando y creo que vengo para quedarme :wink: )

Tengo un fichero.csv con dos columnas de longitud variable:

Nombre_Sede;Red_Sede

La idea es leer ambos valores, abrir un fichero .txt, buscar en él el valor Red_Sede y reemplazarlo por Nombre_Sede.

¿Alguna sugerencia? Lo he hecho con VBscript, pero obviamente con un rendimiento nefasto :-(

Gracias por la ayuda.
bvayap
Perlero nuevo
Perlero nuevo
 
Mensajes: 31
Registrado: 2013-05-31 02:42 @154

Publicidad

Re: Leer y reemplazar cadena de texto

Notapor explorer » 2013-05-31 06:06 @296

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

Esta es una de las muchas posibles soluciones:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;                                # estilo estricto
  3. use warnings;                              # activar advertencias
  4. use diagnostics;                           # diagnósticos de fallos
  5. use autodie;                               # «Es mejor morir que regresar con deshonor» --proverbio Klingon
  6.  
  7. ### Variables
  8. my $archivo;                               # archivo a procesar
  9.  
  10. ### Lectura del archivo a tratar
  11. open my $ARCHIVO, '<', 'archivo.txt';
  12. {
  13.     local $/;                              # activar modo aspiradora
  14.     $archivo = <$ARCHIVO>;                 # lo leemos de una pasada
  15. }
  16. close $ARCHIVO;
  17.  
  18. ### Lectura del archivo CSV
  19. open my $CSV, '<', 'archivo.csv';
  20.  
  21. while (<$CSV>) {                           # para cada línea, hasta fin de archivo
  22.     chomp;                                 # quitamos caracteres fin de línea
  23.     my($nombre, $red) = split /[;]/;       # partimos la línea, extraemos columnas
  24.  
  25.     $archivo =~ s/\b$red\b/$nombre/g;      # cambiamos toda aparición de $red por $nombre, en el $archivo
  26. }
  27.  
  28. close $CSV;
  29.  
  30. ### Grabación del resultado
  31. open my $SALIDA, '>', 'archivo.txt';
  32. print   $SALIDA $archivo;
  33. close   $SALIDA;
Coloreado en 0.004 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 y reemplazar cadena de texto

Notapor bvayap » 2013-05-31 07:05 @336

Muchas gracias por tu respuesta, explorer.

He probado el script y al principio me daba un error (o warning, no sé) diciendo que la variable $ARCHIVO enmascaraba una declaración tardía y que podía ser un error tipográfico, así que he probado a cambiar en las tres últimas lineas de código y utilizar otra variable, $ARCHIVO2. Ahora ya no sale el warning, pero no hace lo que quiero, y creo que es por el cambio que he hecho.

Te paso un ejemplo de los ficheros que gasto:
Sintáxis: (archivo.csv) [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Sede_Cantabria;172.16.18.5
Sede_Leon;172.19.194.101
...
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Sintáxis: (archivo.txt) [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
2013-05-31 09:00:15 172.16.18.5
2013-05-31 09:00:18 172.19.194.101
2013-05-31 09:00:21 172.16.18.5
...
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Al ejecutar el script no da ningún error pero el fichero archivo.txt sigue igual, sin cambiar la IP por el nombre de la sede. ¿Alguna idea sobre el warning/error?

Gracias por tu ayuda
bvayap
Perlero nuevo
Perlero nuevo
 
Mensajes: 31
Registrado: 2013-05-31 02:42 @154

Re: Leer y reemplazar cadena de texto

Notapor danimera » 2013-05-31 09:09 @423

O a mi manera usándolo como una base de datos... manejándolo como una tabla de una DB

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.   $dbh = DBI->connect ("dbi:CSV:") or
  2.         die "Cannot connect: $DBI::errstr";
  3.  
  4.  
  5.     my $sth = $dbh->prepare ("select * from fichero.csv");
  6.     $sth->execute;
  7.     while (my @fila = $sth->fetchrow_array) {
  8.         print "id: $fila [0], name: $fila [1]\n";
  9.         }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Ya recorriendolo así, puedo hacer updates

# Updates
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.   my $sth = $dbh->prepare ("UPDATE fichero.csv SET colunma = ? WHERE colunma= ?");
  2.     $sth->execute ("Nombre_Sede", "red_SEde");
  3.     $sth->finish
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
100% Telch - Perl Web Programming
Cali PerlMongers: http://cali.pm.org
Avatar de Usuario
danimera
Perlero frecuente
Perlero frecuente
 
Mensajes: 871
Registrado: 2005-06-23 19:02 @834
Ubicación: Colombia

Re: Leer y reemplazar cadena de texto

Notapor explorer » 2013-05-31 09:58 @457

Sí, el error era precisamente ese: que habíamos declarado la variable $ARCHIVO dos veces (con my()).

He reeditado el mensaje, lo he probado, y ya funciona:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
> perl code_34828.pl
> cat archivo.txt
2013-05-31 09:00:15 Sede_Cantabria
2013-05-31 09:00:18 Sede_Leon
2013-05-31 09:00:21 Sede_Cantabria
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: Leer y reemplazar cadena de texto

Notapor bvayap » 2013-06-03 06:31 @313

Muchas gracias a ambos.

He probado la solución de explorer y funciona bien. Tengo pendiente probar la de Danimera. Tenía un pequeño problema ya que mi fichero .csv terminaba en ".", pero ya está solucionado. Ahora el problema que tengo es de rendimiento, pero bueno, voy a ver cómo puedo solucionarlo.

Gracias por la ayuda.
bvayap
Perlero nuevo
Perlero nuevo
 
Mensajes: 31
Registrado: 2013-05-31 02:42 @154

Re: Leer y reemplazar cadena de texto

Notapor explorer » 2013-06-03 07:22 @348

Entonces lo haría de otra manera: primero leería todo el archivo CSV y lo guardaría en un hash, y luego recorrería el archivo a cambiar, línea a línea.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;                                     # estilo estricto
  3. use warnings;                                   # activar advertencias
  4. use diagnostics;                                # diagnósticos de fallos
  5. use autodie;                                    # «Es mejor morir que regresar con deshonor» --proverbio Klingon
  6.  
  7. ### Variables
  8. my %redes;                                      # almacén con los cambios
  9.  
  10. ### Lectura del archivo CSV
  11. open my $CSV, '<', 'archivo.csv';
  12.  
  13. while (<$CSV>) {                                # para cada línea, hasta fin de archivo
  14.     chomp;                                      # quitamos caracteres fin de línea
  15.     my($nombre, $red) = split /[;]/;            # partimos la línea, extraemos columnas
  16.  
  17.     $redes{$red} = $nombre;
  18. }
  19.  
  20. close $CSV;
  21.  
  22. ### Procesado
  23. open my $ARCHIVO, '<', 'archivo.txt';           # Lectura del archivo a tratar
  24. open my $SALIDA,  '>', 'archivo.new.txt';       # Escritura del archivo resultado
  25.  
  26. while (my $linea = <$ARCHIVO>) {                # para cada línea del $ARCHIVO
  27.     chomp $linea;
  28.     my $IP = substr $linea, 20;                 # extraemos la IP
  29.  
  30.     if (exists $redes{$IP}) {                   # si tenemos que cambiarla
  31.         substr $linea, 20, length($IP), $redes{$IP};    # la cambiamos
  32.     }
  33.  
  34.     print $SALIDA "$linea\n";                   # guardamos el resultado
  35. }
  36.  
  37. close   $ARCHIVO;
  38. close   $SALIDA;
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 y reemplazar cadena de texto

Notapor bvayap » 2013-06-03 10:13 @467

Gracias por la respuesta, explorer.

No me hace los cambios y creo que es por lo siguiente:

Por lo que entiendo, en la línea se define $IP como todo lo que lea en $linea a partir del carácter 20, ¿no?. El problema es que archivo.txt tiene el formato:

2013-05-31 09:00:15 172.16.18.5 "texto variable"
...

He probado a intentar sacar la length($red), que es la que interesaría leer en la línea 28, pero me da un error de definición de variable global. Así que he probado a comentar la línea use strict (que seguro que es una burrada, pero ya comenté que soy nuevo ;-) y ahora sí me reemplaza las IP por sedes, pero se queda con la longitud de la última red leída de archivo.csv... Te adjunto el código:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;                                     # estilo estricto
  3. use warnings;                                   # activar advertencias
  4. use diagnostics;                                # diagnósticos de fallos
  5. use autodie;                                    # «Es mejor morir que regresar con deshonor» --proverbio Klingon
  6.  
  7. ### Variables
  8. my %redes;                                      # almacén co los cambios
  9. my %longitud;
  10.  
  11. ### Lectura del archivo CSV
  12. open my $CSV, '<', 'archivo.csv';
  13.  
  14. while (<$CSV>) {                                # para cada línea, hasta fin de archivo
  15.     chomp;                                      # quitamos caracteres fin de línea
  16.     my($nombre, $red) = split /[;]/;            # partimos la línea, extraemos columnas
  17.  
  18.     $redes{$red} = $nombre;
  19.         $longitud = length($red);
  20.         print "$longitud\n";
  21. }
  22.  
  23. close $CSV;
  24.  
  25. ### Procesado
  26. open my $ARCHIVO, '<', 'archivo.txt';           # Lectura del archivo a tratar
  27. open my $SALIDA,  '>', 'archivo.new.txt';       # Escritura del archivo resultado
  28.  
  29. while (my $linea = <$ARCHIVO>) {                # para cada línea del $ARCHIVO
  30.     chomp $linea;
  31.     my $IP = substr ($linea, 20, $longitud);                 # extraemos la IP
  32.         print "$IP\n";
  33.  
  34.     if (exists $redes{$IP}) {                   # si tenemos que cambiarla
  35.         substr $linea, 20, length($IP), $redes{$IP};    # la cambiamos
  36.     }
  37.  
  38.     print $SALIDA "$linea\n";                   # guardamos el resultado
  39. }
  40.  
  41. close   $ARCHIVO;
  42. close   $SALIDA;
  43.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
bvayap
Perlero nuevo
Perlero nuevo
 
Mensajes: 31
Registrado: 2013-05-31 02:42 @154

Re: Leer y reemplazar cadena de texto

Notapor explorer » 2013-06-03 10:29 @478

Se puede adoptar otra estrategia: como el archivo consiste en cuatro campos separados por espacios en blanco, podemos usar split() para extraerlos, y join() para recrear los registros:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;                                     # estilo estricto
  3. use warnings;                                   # activar advertencias
  4. use diagnostics;                                # diagnósticos de fallos
  5. use autodie;                                    # «Es mejor morir que regresar con deshonor» --proverbio Klingon
  6.  
  7. ### Variables
  8. my %redes;                                      # almacén con los cambios
  9.  
  10. ### Lectura del archivo CSV
  11. open my $CSV, '<', 'archivo.csv';
  12.  
  13. while (<$CSV>) {                                # para cada línea, hasta fin de archivo
  14.     chomp;                                      # quitamos caracteres fin de línea
  15.     my($nombre, $red) = split /[;]/;            # partimos la línea, extraemos columnas
  16.  
  17.     $redes{$red} = $nombre;
  18. }
  19.  
  20. close $CSV;
  21.  
  22. ### Procesado
  23. open my $ARCHIVO, '<', 'archivo.txt';           # Lectura del archivo a tratar
  24. open my $SALIDA,  '>', 'archivo.new.txt';       # Escritura del archivo resultado
  25.  
  26. while (my $linea = <$ARCHIVO>) {                # para cada línea del $ARCHIVO
  27.     my(@campos) = split " ", $linea, 4;         # partir en cuatro cachos
  28.     my $IP = $campos[2];
  29.  
  30.     if (exists $redes{$IP}) {                   # si tenemos que cambiarla
  31.         $campos[2] = $redes{$IP};               # la cambiamos
  32.     }
  33.  
  34.     print $SALIDA join " ", @campos;            # guardamos el resultado
  35. }
  36.  
  37. close   $ARCHIVO;
  38. close   $SALIDA;
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 y reemplazar cadena de texto

Notapor bvayap » 2013-06-03 10:55 @497

Muchas gracias, explorer. Funciona de maravilla y con un rendimiento asombroso comparado con lo que yo había hecho :shock:

Voy a intentar ahora buscar una cadena en el cuarto campo y, si existe, reemplazar todo el campo, además de intentar ignorar las 6 primeras líneas del archivo.txt, ya que son una cabecera que debo ignorar.

Si me surge alguna duda, vuelvo al ataque ;-)

Gracias por vuestra ayuda.
bvayap
Perlero nuevo
Perlero nuevo
 
Mensajes: 31
Registrado: 2013-05-31 02:42 @154

Siguiente

Volver a Básico

¿Quién está conectado?

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