Página 1 de 1

Aplicar script al contenido de una carpeta

NotaPublicado: 2014-01-24 10:20 @472
por sisifo80
Hola,

Estoy un poco perdido con las entradas y salidas en la aplicación de scripts. Es decir, normalmente los script básicos que necesito son para editar un .txt. Entonces, suelo empezar el script:

open F, shift;
while (<F>) {bla bla bla...
close F;

Y para aplicarlo guardo en una misma carpeta el script .pl y el archivo .txt que quiero editar. Después abro la consola de comandos, me ubico en esa carpeta y aplico el script:

perl nombre_del_script.pl input.txt > output.txt

Bien, mi problema es que ahora necesito aplicar un script que edite varios archivos .txt guardados en una misma carpeta y no sé cómo empezar el script ni qué debo teclear en la consola de comandos.

¿Alguien me puede explicar brevemente (o sugerirme dónde encontrar información al respecto) la lógica de este tipo de operaciones? Es decir, cómo empezar los scripts y cómo aplicarlos en la consola de comandos en función de la entrada y salida que uno quiera, y en función de si se va a aplicar a un solo archivo o a varios.

Gracias.

Re: Aplicar script al contenido de una carpeta

NotaPublicado: 2014-01-24 13:06 @587
por explorer
Se puede hacer de varias formas.

De las que se me ocurren ahora:
  • pasar al programa el nombre de la carpeta. El programa lo lee, entra en la carpeta, y procesa todos los txt que encuentre
    Sintáxis: [ Descargar ] [ Ocultar ]
    Using perl Syntax Highlighting
    1. my $carpeta = $ARGV[0];
    2. chdir $carpeta or die "ERROR: no puedo entrar en $carpeta: $!\n";
    3. for my $archivo (<*.txt>) {
    4.     print "Procesando archivo $archivo...\n";
    5.     ...;
    6. }
    Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
  • pasar al programa todos los archivos que queremos procesar. Ejecutamos el programa así: programa.pl carpeta/*.txt
    Sintáxis: [ Descargar ] [ Ocultar ]
    Using perl Syntax Highlighting
    1. for my $archivo (@ARGV) {
    2.     print "Procesando archivo $archivo...\n";
    3.     ...;
    4. }
    Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
  • si la carpeta siempre es la misma, podemos entrar en ella y procesar los archivos que estén dentro
    Sintáxis: [ Descargar ] [ Ocultar ]
    Using perl Syntax Highlighting
    1. chdir 'carpeta' or die "ERROR: no puedo entrar en carpeta: $!\n";
    2. for my $archivo (<*.txt>) {
    3.     print "Procesando archivo $archivo...\n";
    4.     ...;
    5. }
    Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
    o así:
    Sintáxis: [ Descargar ] [ Ocultar ]
    Using perl Syntax Highlighting
    1. for my $archivo (<carpeta/*.txt>) {
    2.     print "Procesando archivo $archivo...\n";
    3.     ...;
    4. }
    Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Naturalmente, si en el código ponemos la ruta absoluta (completa) a la carpeta, entonces podemos ejecutar el programa desde cualquier otro directorio del sistema.

Re: Aplicar script al contenido de una carpeta

NotaPublicado: 2014-01-25 05:30 @271
por sisifo80
Muchas gracias por tu explicación "explorer". Solo una última duda. No sé cómo enlazar tu plantilla con los datos específicos que yo quiero insertar. Por ejemplo, imaginemos que escojo tu primera opción y que quiero sustituir en mis textos todos los casos de "blue" por "red". Yo he intentado lo siguiente:

1. Coloco todos mis archivos .txt en una carpeta llamada "carpeta"
2. Coloco mi script ("cambiarcolores.pl") en el mismo directorio que está la carpeta llamada "carpeta"
3. Abro la consola de comandos y me sitúo en el directorio donde tengo el script.
4. Ejecuto lo siguiente: perl cambiarcolores.pl carpeta
5. El script sería el siguiente:

Sintáxis: [ Descargar ] [ Ocultar ]
  1. my $carpeta = $ARGV[0]; 
  2. chdir $carpeta or die "ERROR: no puedo entrar en $carpeta: $!\n"; 
  3. for my $archivo (<*.txt>) { 
  4. print "Procesando archivo $archivo...\n"; 
  5. open F, shift; 
  6. while (<F>) { 
  7. s/blue/red/g; 
  8. print; 
  9. close F; 


¿Qué estoy haciendo mal? (pues no se aplican los cambios a mis .txt)

Re: Aplicar script al contenido de una carpeta

NotaPublicado: 2014-01-25 07:42 @362
por explorer
Pues hay varios errores:
  • Usas shift() para obtener el nombre del archivo a partir de @ARGV, pero resulta que ahí no está, sino en la variable $archivo, que es actualizada en cada vuelta del bucle for()
  • Abres el archivo y lo vas modificando línea a línea, y sacando por la pantalla, pero no le has dicho a Perl dónde ni con qué nombre guardarlo
  • El close() del archivo abierto está fuera del bucle for
Para lo que quieres hacer, te recomiendo el uso de Tie::File (Ejemplo de uso, en inglés)

Re: Aplicar script al contenido de una carpeta

NotaPublicado: 2014-01-25 10:29 @478
por sisifo80
Gracias de nuevo por tus comentarios, explorer. Lamentablemente, se ve que no tengo los conocimientos básicos para poder aplicar tus sugerencias. He intentado esto sin éxito (posiblemente porque me falta aplicar tu segunda sugerencia, que no sé cómo hacer):

my $carpeta = $ARGV[0];
chdir $carpeta or die "ERROR: no puedo entrar en $carpeta: $!\n";
for my $archivo (<*.txt>) {
print "Procesando archivo $archivo...\n";
open F, $archivo;
while(<F>) {
s/blue/red/g;
close F;
}
}

También lo he intentado con la opción Tie:File que me comentas, pero en este caso no sé cómo aplicar el ejemplo del enlace a mi caso particular. Mi intento sin éxito...

tie my @file, 'Tie::File', $file;
@file = grep !$seen{$_}++,
s/blue/red/;
untie @file;

Como ves, estoy bastante perdido :)

Re: Aplicar script al contenido de una carpeta

NotaPublicado: 2014-01-25 13:02 @584
por explorer
Una forma simple:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use autodie;
  2.  
  3. my $carpeta = $ARGV[0];
  4. chdir $carpeta;
  5.  
  6. for my $archivo (<*.txt>) {
  7.     print "Procesando archivo $archivo... ";
  8.  
  9.     open F, "<$archivo";             # abrimos en lectura
  10.     my @lineas = <F>;                # leemos todas las líneas
  11.     close F;
  12.  
  13.     open W, ">$archivo";             # abrimos en escritura
  14.     for my $linea (@lineas) {        # para cada $linea de todas las @lineas
  15.         $linea =~ s/blue/red/g;      # modificamos la $linea
  16.         print W $linea;              # guardamos la $linea
  17.     }
  18.     close W;
  19.  
  20.     print "Ok\n";
  21. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Otra forma, usando Tie::File (no probado, sacado de la página de manual de Tie::File):
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use Tie::File;
  2.  
  3. my $carpeta = $ARGV[0];
  4. chdir $carpeta;
  5.  
  6. for my $archivo (<*.txt>) {
  7.     print "Procesando archivo $archivo... ";
  8.  
  9.     tie my @lineas, 'Tie::File', $archivo;
  10.  
  11.     for (@lineas) {                  # para cada línea de todas las @lineas
  12.         s/blue/red/g;                # modificamos la línea y se guarda
  13.     }
  14.  
  15.     untie @lineas;                   # fin del enlazado
  16.  
  17.     print "Ok\n";
  18. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Re: Aplicar script al contenido de una carpeta

NotaPublicado: 2014-01-26 07:53 @370
por sisifo80
Tomo nota, explorer. Mil gracias por tu respuesta, por tus aclaraciones y por tu paciencia.