• Publicidad

Modificar diversos ficheros a la vez en un directorio

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

Modificar diversos ficheros a la vez en un directorio

Notapor enric73 » 2014-04-14 15:51 @702

Hola, tengo una consulta: Cómo puedo modificar a la vez una palabra por otra en el nombre de unos ficheros y en su contenido.
El nombre de los ficheros tiene un patrón común, plujatempabril.htm, todos empiezan por el nombre de una población. Por ejemplo, Barcelonaplujatempabril.htm, Valenciaplujatempabril.htm... Quiero cambiar abril por mayo... en el nombre de los ficheros y en el interior de los ficheros. En el siguiente código realizo el cambio para un fichero en concreto, pero para todos ¿cómo debo hacerlo? Gracias.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. chdir "$ENV{HOME}/htm/prova";
  2.  
  3. #open(LS, "ls *plujatempabril.htm") or die $!;
  4. #while (<*plujatempabril.>){
  5. my $archivo = 'olotplujatempabril';
  6. open my $INFILE, '<', "$archivo.htm";
  7. my @archivo = <$INFILE>;
  8. foreach (@archivo) {
  9.     s/abril/mayo/g;
  10.     s/Abril/Mayo/g;
  11. }
  12.  
  13. #chomp $archivo[-1];
  14. close $INFILE;
  15. open my $OUTFILE, '>', "olotplujatempmayo.htm";
  16. print $OUTFILE @archivo;
  17. close $OUTFILE;
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4

Gracias otra vez.
enric73
Perlero nuevo
Perlero nuevo
 
Mensajes: 154
Registrado: 2012-03-16 06:27 @311

Publicidad

Re: Modificar diversos ficheros a la vez en un directorio

Notapor explorer » 2014-04-14 17:23 @766

Bueno, son dos procesos distintos: el interior y el nombre del archivo.

Yo leería el contenido, haría el cambio en el interior, y luego grabaría el resultado en el nuevo archivo (así, el archivo anterior no lo pierdo).
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use autodie;
  2.  
  3. my $patro     = 'plujatempabril.htm';
  4. my $patro_nou = 'plujatempmayo.htm';
  5.  
  6. chdir "$ENV{HOME}/htm/prova";
  7.  
  8. while (my $arxiu = <*$patro>) {                 # mientras existan archivos coincidentes con el patrón
  9.  
  10.     my($ciutat) = $arxiu =~ /^(\w+)$patro/;     # extracción del nombre de la ciudad: es lo que hay delante del patrón
  11.  
  12.     open my $INFILE, '<', $arxiu;               # abrimos
  13.     open my $OUTFILE,'>', "$ciutat$patro_nou";
  14.  
  15.     while(<$INFILE>) {                          # leemos
  16.         s/abril/mayo/g;                         # cambiamos
  17.         s/Abril/Mayo/g;
  18.  
  19.         print $OUTFILE $_;                      # escribimos
  20.     }
  21.     close $INFILE;                              # y nos vamos
  22.     close $OUTFILE;
  23. }
Coloreado en 0.001 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: Modificar diversos ficheros a la vez en un directorio

Notapor enric73 » 2014-04-15 10:45 @489

Gracias, explorer.

Entiendo el código, pero solamente me crea un fichero plujatempmayo.htm y dentro está el contenido de la última población y con las palabras mayo y Mayo. No reconoce $ciutat...
enric73
Perlero nuevo
Perlero nuevo
 
Mensajes: 154
Registrado: 2012-03-16 06:27 @311

Re: Modificar diversos ficheros a la vez en un directorio

Notapor explorer » 2014-04-15 11:44 @530

Ya está arreglado. Hay que cambiar $archivo por $arxiu en la línea 10.
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: Modificar diversos ficheros a la vez en un directorio

Notapor enric73 » 2014-04-16 04:17 @220

Gracias, explorer.

Hay una línea que no entiendo, en concreto esta:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my($ciutat) = $arxiu =~ /^(\w+)$patro/;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

$arxiu es el nombre completo del archivo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $arxiu = <*$patro>
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
pero en la línea 10, lo igualamos a my($ciutat), no llego a entenderlo.

Saludos.
enric73
Perlero nuevo
Perlero nuevo
 
Mensajes: 154
Registrado: 2012-03-16 06:27 @311

Re: Modificar diversos ficheros a la vez en un directorio

Notapor explorer » 2014-04-16 07:36 @358

En la línea 8, con la ayuda del operador diamante, vamos obteniendo un nombre de archivo completo, en cada vuelta del while().

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. while (my $arxiu = <*$patro>) {
  2.  
  3.     my($ciutat) = $arxiu =~ /^(\w+)$patro/;
  4.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

En la línea 8, se recorre cada nombre de archivo que coincida con el patrón. $arxiu va tomando cada nombre de archivo.

Por ejemplo, en una vuelta sería $arxiu igual a 'Barcelonaplujatempabril.htm'.

A continuación viene la línea 10. En ella, aplicamos la expresión regular a $arxiu. La expresión regular lo que hace es:
  • busca desde el comienzo de la cadena de caracteres (^)
  • seguido por uno o más (+) caracteres alfanuméricos (\w)
  • esos caracteres serán capturados (())
  • y deben ser seguidos por el patrón $patro
Si el nombre del archivo coincide con todo este patrón, tendremos capturado en $1 el comienzo del nombre del archivo. En nuestro ejemplo, 'Barcelona'.

Luego, Perl mira a la izquierda. Y lo que se encuentra es un par de paréntesis: my($ciutat). Entonces, el comportamiento de la expresión regular cambia, porque Perl se da cuenta de que se está ejecutando en contexto de lista, no en contexto de escalar.

Si hubiéramos escrito my $ciutat = $arxiu =~ /^(\w+)$patro/; (sin los paréntesis), estaríamos ejecutándolo en contexto escalar, y el resultado que se almacena en $ciutat sería un valor de verdad '1' (verdadero) o '' (cadena nula, falso), para indicar si la expresión regular ha conseguido una coincidencia entre $arxiu y el patrón.

Pero... al poner los paréntesis a la izquierda, estamos queriendo decir que queremos que se ejecute en contexto de lista, y la consecuencia de ello es que la exp. reg. devuelve una lista de valores, que serán las capturas hechas dentro del patrón.

En el patrón solo tenemos un par de paréntesis de captura, así que la exp. reg. devuelve una lista de valores de un solo valor ('Barcelona'). Y se almacena en las variables que están entre los paréntesis de la izquierda.

Así que 'Barcelona' se almacena en $ciutat, que usaremos luego en la línea 13 para crear el nuevo nombre de archivo.
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: Modificar diversos ficheros a la vez en un directorio

Notapor enric73 » 2014-04-17 14:01 @625

Muchas gracias, explorer, por esta explicación tan desarrollada. Saludos.
enric73
Perlero nuevo
Perlero nuevo
 
Mensajes: 154
Registrado: 2012-03-16 06:27 @311

Re: Modificar diversos ficheros a la vez en un directorio

Notapor enric73 » 2014-04-17 16:17 @720

Una última pregunta sobre este asunto... si quisiera mantener el mismo nombre de fichero, que el nombre del $OUTPUT sea igual al $INPUT, ¿cómo se procede? He estado modificando '<', pero el fichero que me guarda está vacío.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open my $INFILE, '<', $arxiu;               # abrimos
  2. open my $OUTFILE,'>', "$ciutat$patro_nou";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
enric73
Perlero nuevo
Perlero nuevo
 
Mensajes: 154
Registrado: 2012-03-16 06:27 @311

Re: Modificar diversos ficheros a la vez en un directorio

Notapor explorer » 2014-04-17 16:39 @735

Lo que puedes hacer es que la salida vaya a un archivo con un nombre temporal, y cuando hayas terminado de sacar todas las filas, haces un move() desde el nombre temporal al definitivo. El move() lo encuentras en el módulo File::Copy.
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 13 invitados