• Publicidad

Abrir directorio, leer todos los archivos y unirlos

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

Abrir directorio, leer todos los archivos y unirlos

Notapor pablgonz » 2012-06-06 01:48 @117

Hola a todos, tengo el siguiente problema:

Tengo varios directorios (alrededor de 40) de nombre images/ y dentro de ellos tengo ficheros llamados nombre-pst-1.tex, nombre-pst-2.tex, nombre-pst-3.tex, etc, donde nombre es cualquier nombre (o número), todos los ficheros tiene la siguiente forma:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \documentclass{article}
  2. \usepackage{uno}
  3. \usepackage{dos}
  4. \begin{document}
  5. me interesa esto 1 ...
  6. \end{document}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Me interesa leer el contenido de todos estos ficheros entre las líneas:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \begin{document}
  2. me interesa esto 1 ...
  3. \end{document}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
sin considerar éstas, y pegarlos en un nuevo fichero (masterimg.tex) que tenga esta forma
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \documentclass{article}
  2. \usepackage{pstricks-add}
  3. \pagestyle{empty}
  4. \begin{document}
  5. me interesa esto 1 ...
  6. %fig1
  7. \newpage
  8. me interesa esto 1 ...
  9. %fig2
  10. \newpage
  11. me interesa esto 1 ...
  12. %fig3
  13. \newpage
  14. ...
  15. \end{document}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Me aventuré a resolverlo con sed, pero creo que una solución en Perl sería lo óptimo.

Sé que con split() puedo dividir los ficheros de entrada y guardar lo que necesito en otro (lo logré en un script anterior) y luego con cat (o sed) puedo unirlos usando algunas líneas en bash.

Mi idea es automatizarlo usando Perl que es más rápido y eficaz en estos asuntos.

Si me pueden prestar ayuda con un esqueleto de código se los agradezco.

Saludos,
Pablo
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Publicidad

Re: Abrir directorio, leer todos los archivos y unirlos

Notapor explorer » 2012-06-06 11:40 @528

Esta es una manera...
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2. use v5.14;                      # Somos modernos
  3. use autodie;                    # «Es mejor morir que regresar con deshonor» --proverbio Klingon
  4.  
  5. # 1- Leer los archivos
  6. my @archivos = glob('images/*.tex');
  7. @archivos or die "ERROR: No encuentro archivos en 'images/*.tex':$!\n";
  8.  
  9. # 2- Ordenar según el índice
  10. @archivos =
  11.     map  { $_->[1]                       }
  12.     sort { $a->[0] <=> $b->[0]           }
  13.     map  { [ ($_ =~ /(\d+)\.tex$/), $_ ] }
  14.     @archivos;
  15.  
  16. say "Número de archivos encontrados: ", scalar @archivos;
  17.  
  18.  
  19. # 3- Bucle para leer las secciones
  20. my @almacen;
  21. for my $archivo (@archivos) {
  22.  
  23.     # 3.1- Leer el archivo
  24.     open my $FH, '<:crlf', $archivo;                # Filtrar apropiadamente los finales de línea
  25.     my $tex = join q{}, <$FH>;                       # ¡Ñam!
  26.     close   $FH;
  27.  
  28.     # 3.2- Extraer la parte que nos interesa
  29.     my($pedazo) = $tex =~ m/\\begin\{document\}\n(.+?)\n\\end\{document\}/sm;
  30.  
  31.     # 3.3- Almacenamos, si hemos encontrado algo
  32.     push @almacen, $pedazo if $pedazo;
  33. }
  34.  
  35. say "Número de pedazos  encontrados: ", scalar @almacen;
  36. @almacen or die "ERROR: no hay nada que escribir: \@almacen vacío.\n";
  37.  
  38.  
  39. # 4- Salida
  40. open my $SALIDA, '>', 'masterimg.tex';
  41.  
  42. print $SALIDA <<'EOH';
  43. \documentclass{article}
  44. \usepackage{pstricks-add}
  45. \pagestyle{empty}
  46. \begin{document}
  47. EOH
  48.  
  49. my $fig = 1;
  50. for my $item (@almacen) {
  51.  
  52.     say $SALIDA $item;
  53.     say $SALIDA '%fig' . $fig;
  54.     say $SALIDA '\newpage';
  55.  
  56.     $fig++;
  57. }
  58.  
  59. say $SALIDA '\end{document}';
  60.  
  61. close $SALIDA;
  62.  
  63. __END__
Coloreado en 0.003 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: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Abrir directorio, leer todos los archivos y unirlos

Notapor pablgonz » 2012-06-06 20:47 @907

Gracias por la pronta respuesta explorer. Instalé el módulo y sus dependencias, pero, me arroja el siguiente error:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
  1. Use of uninitialized value $file_name in -e at /usr/share/perl5/vendor_perl/File/Slurp.pm line 116.
  2. Use of uninitialized value $file_name in sysopen at /usr/share/perl5/vendor_perl/File/Slurp.pm line 193.
  3. Use of uninitialized value $file_name in concatenation (.) or string at /usr/share/perl5/vendor_perl/File/Slurp.pm line 194.
  4. read_file '' - sysopen: No existe el fichero o el directorio at joinfif line 22
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
estoy usando Fedora 17 , la información de Perl es:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
  1. perl 5, versión 14, subversión 2 (v5.14.2) built for i386-linux-thread-multi
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Si cambio la línea
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
por
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -w
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
lo puedo ejecutar, pero, el fichero generado solo contiene:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \documentclass{article}
  2. \usepackage{pstricks-add}
  3. \pagestyle{empty}
  4. \begin{document}
  5. \end{document}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

¿Tengo algo mal configurado? ¿O se debe modificar alguna línea?
Saludos
Última edición por pablgonz el 2012-06-07 06:30 @312, editado 1 vez en total
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Abrir directorio, leer todos los archivos y unirlos

Notapor explorer » 2012-06-07 03:14 @177

Deja el programa como estaba, y solo mete esta línea:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. @archivos or die "ERROR: No encuentro archivos en 'images/*.tex':$!\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


El error es que no ha encontrado ningún archivo dentro de la carpeta 'images/'. A lo mejor tienes que cambiar la línea 7 para poder llegar (ruta) a los archivos.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Abrir directorio, leer todos los archivos y unirlos

Notapor pablgonz » 2012-06-07 06:29 @311

Gracias explorer, agregué la línea que me diste. Ahora no muestra errores en pantalla pero, el archivo que genera (masterimg.tex) no contiene lo que deseo, sigue siendo de la forma:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \documentclass{article}
  2. \usepackage{pstricks-add}
  3. \pagestyle{empty}
  4. \begin{document}
  5. \end{document}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
¿Alguna idea...? En el directorio (home/pablo/images) están los archivos en cuestión (numerados como ang-pst-1.tex, ang-pst-2.tex,..., ang-pst-20.tex).

Dentro del directorio images/ creé el fichero ang.tex, al correr el script, éste me arroja un error (sort) lo cual me indica que sí está leyendo el directorio, pero no captura lo que se desea.

Saludos,
Pablo
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Abrir directorio, leer todos los archivos y unirlos

Notapor explorer » 2012-06-07 18:21 @806

Entonces el problema está en la expresión regular.

Es posible que los tex, en lugar de tener finales de línea al estilo Unix (\n) los tenga al de MSDOS (\r\n).

He modificado el programa para que sea más robusto.

Aparte de modificar otras partes del programa, he cambiado la exp. reg. por otra más genérica, seguida de dos líneas dedicadas a quitar los avances de línea del principio y del final del $pedazo que hemos sacado. Se podía haber hecho en la misma exp. reg. pero así queda más claro.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Abrir directorio, leer todos los archivos y unirlos

Notapor pablgonz » 2012-06-07 20:04 @878

Lo probé, me arroja lo siguiente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
  1. Número de archivos encontrados: 18
  2. Número de pedazos  encontrados: 0
  3. ERROR: no hay nada que escribir: @almacen vacío.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


En el directorio images/ tengo ficheros ang-pst-1.tex,...,ang-pst-18.tex, la lectura de los ficheros es correcta, el tema es que no captura lo que debería capturar, lo de los finales de línea, hummmm... no creo: estos ficheros son generados por otro script, que corro en Linux. Creo que el problema está en la expresión regular que busca entre \begin{...} y \end{...}.

Un par de consultas (aprovecho)
1- ¿Por qué usas die (en la 8), si ya está cargado autodie?
2- Entre las líneas 44-47, ¿no se deben escapar los caracteres '\', '{','}'?
3- Actualicé Perl usando cpan upgrade. ¿Es bueno hacer esto, o debo esperar a las actualizaciones proporcionadas por la distribución (Fedora en este caso)?

Saludos
Pablo
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Abrir directorio, leer todos los archivos y unirlos

Notapor explorer » 2012-06-08 09:13 @425

Sí, suponiendo que los archivos son leídos en la línea 23, el problema estaría en la exp. reg.

Puedes poner en la línea 24 esta línea para verificar que, efectivamente, hemos leído el contenido del archivo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     say "Leídos ", length($tex), " bytes del archivo $archivo";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Puedes adjuntar uno de esos archivos, quitándole antes todas las líneas no interesantes? Yo he hecho pruebas con archivos siguiendo el formato que has descrito, y me funciona, pero no sé si habrá alguna condición más. Por ejemplo, fallará si \begin o \end no están en la primera columna del archivo.

Consultas:
1- autodie hace un die() en muchas operaciones, pero no en todas. Por defecto, en los open, close, print, say... pero no en en resto de condiciones. La línea 8 es la comprobación de una condición. Y si falla, queremos que muera (en este caso, podría ser un comportamiento distinto en otros casos)

2- No, porque son cadenas literales de un print(). Incluso les he puesto comillas simples a 'EOH'. Eso indica que son literales (tal cual son)

3- El Perl que trae el sistema (y sus módulos) hay que actualizarle usando siempre el gestor de paquetes del sistema (yum, no cpan). El objetivo es usar cpan lo menos posible. Solo cuando un módulo no esté soportado directamente por el gestor de paquetes, entonces sí que usaremos cpan.

En los últimos años, ya existen herramientas para trabajar de forma completamente independiente del Perl del sistema, y de los módulos instalados. Con cosas como perlbrew puedes tener y gestionar uno o más versiones de Perl en tu propio directorio personal. Y su colección particular de módulos.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Abrir directorio, leer todos los archivos y unirlos

Notapor pablgonz » 2012-06-08 10:57 @498

Gracias por la respuesta explorer. Te adjunto un par de archivos. En este momento no dispongo de Perl. Cuando llegue a casa pruebo lo que me comentas.
Saludos

PD: Estos ficheros están creados en Windows, para descartar lo del fin de línea.
Adjuntos
foro.rar
(1.45 KiB) 35 veces
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Abrir directorio, leer todos los archivos y unirlos

Notapor explorer » 2012-06-08 14:13 @634

Vale, ya está.

He modificado el programa y me funciona.

Los archivos están en MSDOS, y los leo desde Linux.

La capa ':crlf' hace la transformación de "\r\n" a "\n", con lo que luego puedo usar "\n" en la expresión regular. Además, me ahorro un par de líneas que tenía puesto antes.

A propósito, acabo de descubrir que File::Slurp no es tan maravilloso como parece... El argumento "binmode => ':crlf'" no funciona.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Siguiente

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado