• Publicidad

Copiar bloques de texto en archivos separados

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

Re: Copiar bloques de texto en archivos separados

Notapor pablgonz » 2014-03-14 08:58 @415

Genial, ¿las líneas que propones son equivalentes? Lo pregunto puesto que en la segunda línea usas solo (.+?) y no sé si esta expresión captura las líneas en blanco.

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

Publicidad

Re: Copiar bloques de texto en archivos separados

Notapor pablgonz » 2014-03-15 23:23 @016

Modifiqué la línea a la que me propusiste:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my($cabeza,$cuerpo,$final) = $archivo =~ m/\A (.+? ^\\begin{document}) (\s* .+? \s*) (^ \\end{document}) .+? \z/msx;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
pero creo que tengo algo mal colocado en el script. Si el archivo de entrada es así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \documentclass{article}
  2. \usepackage{pstricks}
  3. \tcbuselibrary{listings,
  4.                          breakable,
  5.                        skins}
  6. \begin{document}
  7.  
  8. Este texto va acá
  9.  
  10. \begin{MYexample}[
  11.                    justification=\centering
  12.                  ]
  13. Bloque 1 que deseo extraer
  14. \end{MYexample}
  15. Acá va más texto
  16. \begin{verbatim}
  17. \begin{document}
  18. Texto cualquiera
  19. \end{document}
  20. \end{verbatim}
  21. Acá va más texto
  22. \begin{MYexample}
  23. Bloque 2 que deseo extraer
  24. \end{MYexample}
  25.  
  26. \end{document}
  27. El texto que va acá no debería ser modificado
  28. \begin{MYexample}
  29. Bloque 3 no deseo extraerlo ni modificarlo
  30. \end{MYexample}
  31.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
debería quedar en $cabeza
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \documentclass{article}
  2. \usepackage{pstricks}
  3. \tcbuselibrary{listings,
  4.                          breakable,
  5.                        skins}
  6. \begin{document}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
en $cuerpo aparece
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1.  
  2. Este texto va acá
  3.  
  4. \begin{MYexample}[
  5.                    justification=\centering
  6.                  ]
  7. Bloque 1 que deseo extraer
  8. \end{MYexample}
  9. Acá va más texto
  10. \begin{verbatim}
  11. \begin{document}
  12. Texto cualquiera
  13. \end{document}
  14. \end{verbatim}
  15. Acá va más texto
  16. \begin{MYexample}
  17. Bloque 2 que deseo extraer
  18. \end{MYexample}
  19.  
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
y en $final aparece
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \end{document}
  2. El texto que va acá no debería ser modificado
  3. \begin{MYexample}
  4. Bloque 3 no deseo extraerlo ni modificarlo
  5. \end{MYexample}
  6.  
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
Es decir, en $cuerpo debería estar todo lo contenido entre la primera aparición de \begin{document} y la última aparición de \end{document} y leer y modificar dentro de este rango; en $final debería estar todo lo que va después del último \end{document} si es que que está presente.

Sé que \z marca el final de la cadena que busco, pero, no me funciona, el script lo tengo así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use v5.14;
  3. use autodie;                                            # muere si ocurre un error
  4. use File::Basename;                                     # separa el archivo de entrada
  5.  
  6. ### Constantes --------------------------------------------------------------
  7. my $imageDir = 'images/';                               # directorio de imágenes
  8. my $graphics = 'graphic={[scale=1]images/test-src';
  9.  
  10. ### Argumentos --------------------------------------------------------------
  11. @ARGV == 1  or die "Uso: $0 <archivo TeX a procesar>\n";
  12. my $nombre_archivo = shift;
  13. -f $nombre_archivo or die "ERROR: No encuentro [$nombre_archivo]\n";
  14.  
  15. ### Directorio destino ------------------------------------------------------
  16. -e $imageDir or mkdir($imageDir,0744) or die "No puedo crear $imageDir: $!\n";
  17.  
  18. ### Arreglo de la extensión -------------------------------------------------
  19. my @SuffixList = ('.tex', '', '.ltx');                  # posible extensión
  20. my ($name, $path, $ext) = fileparse($nombre_archivo, @SuffixList);
  21. $ext = '.tex' if not $ext;                              # fijamos la extensión
  22. my $nuevo_nombre_archivo = "$path$name-nuevo$ext";
  23.  
  24. ### Proceso 1 : Ajustamos el archivo original -------------------------------
  25. open my $ENTRADA, '<', $nombre_archivo;
  26. my $archivo;
  27. {
  28.     local $/;
  29.     $archivo = <$ENTRADA>;
  30. }
  31. close   $ENTRADA;
  32.  
  33. my $contador = 1;
  34. # Dividimos
  35. my($cabeza,$cuerpo,$final) = $archivo =~ m/\A (.+? ^\\begin{document}) (\s* .+? \s*) (^ \\end{document}\s* .+? \s*)  \z/msx;
  36. # Poner el atributo añadido a \begin{MYexample}
  37. while ($cuerpo =~ /^\\begin\{MYexample\}(\[.+?\])?/gsm) {
  38.  
  39.     my $corchetes = $1;
  40.     my($pos_inicial, $pos_final) = ($-[1], $+[1]);      # posición donde están los corchetes
  41.  
  42.     if (not $corchetes) {
  43.         $pos_inicial = $pos_final = $+[0];              # si no hay corchetes, nos ponemos al final de \begin
  44.     }
  45.  
  46.     if (not $corchetes  or  $corchetes =~ /\[\s*\]/) {  # si no hay corchetes, o están vacíos,
  47.         $corchetes = "[$graphics-$contador}]";          # ponemos los nuestros
  48.     }
  49.     else {                                              # si sí hay corchetes,
  50.         $corchetes =~ s/\]/,$graphics-$contador}]/;     # lo agregamos al final, dentro de los corchetes
  51.     }
  52.  
  53.     substr($cuerpo, $pos_inicial, $pos_final - $pos_inicial) = $corchetes;    
  54.     pos($cuerpo) = $pos_inicial + length $corchetes;    # reposicionamos la búsqueda de la exp. reg.
  55. }
  56. continue {
  57.     $contador++;
  58. }
  59.  
  60. open my $SALIDA, '>', $nuevo_nombre_archivo;
  61. print $SALIDA "$cabeza$cuerpo$final";
  62. close $SALIDA;
  63. ### Proceso 2 : Extraer los archivos secundarios ----------------------------
  64. while ($cuerpo =~ /^\\begin\{MYexample\}\[.+?(?<nombre_archivo_secundario>images\/.+?-\d+)\}\](?<contenido>.+?)(?=^\\end\{MYexample})/gsm) {
  65.     open my $SALIDA, '>', "$+{'nombre_archivo_secundario'}.tex";
  66.     print $SALIDA <<"EOC";
  67. $cabeza\n\\thispagestyle{empty}$+{'contenido'}$final
  68. EOC
  69.     close $SALIDA;
  70. }
  71.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
Agradecido por la ayuda,
Pablo
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Copiar bloques de texto en archivos separados

Notapor explorer » 2014-03-16 12:12 @550

El problema está en el comodín '.*?'. El '?' tiene el efecto de parar la búsqueda en la primera concordancia del patrón que sigue al comodín, por lo que entonces se para en el primer '\end{document}' que encuentra.

Cambiando un poco la expresión regular, ya sale bien:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my($cabeza,$cuerpo,$final) = $archivo =~ m/\A (.+? ^\\begin{document}) (.+) (^ \\end{document} .*) \z/msx;
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: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Copiar bloques de texto en archivos separados

Notapor pablgonz » 2014-03-16 12:55 @580

Genial, ahora sí funciona a la perfección, me estaba cabeceando con buscar adelante y atrás (muy avanzado para mi) y bastaba con recordar algo básico como el comportamiento de *.

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

Re: Copiar bloques de texto en archivos separados

Notapor pablgonz » 2014-04-07 22:57 @998

Hola de nuevo, agregué un par de cosas al script y me pregunto si no existe una manera más elegante de llevar a cabo lo siguiente: Leer el directorio que contiene los archivos separados (images/) y ejecutar un par de comandos de sistema sobre todos ellos.

Escribo el código para ver si me explico mejor
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $tempDir = ".";                     # directorio temporal
  2.  
  3. # Compilamos en forma individual cada fichero
  4. my $fich = '';
  5. if ( opendir( DIR, $imageDir ) ) {
  6.     foreach ( readdir DIR ) {
  7.         $fich = $_;
  8.         if ( $fich =~ /($name-src-)(\d+)($ext)/ ) {
  9.             system("latex $imageDir/$1$2$3");
  10.             system("dvips -Ppdf $tempDir/$1$2\.dvi");
  11.             system("ps2pdf $tempDir/$1$2\.ps");
  12.             system("pdfcrop -margins 1 $tempDir/$1$2\.pdf $imageDir/$1$2\.pdf");
  13.         }
  14.     }
  15.     closedir DIR;
  16.     unlink <$tempDir/$name-src-*.aux>;
  17.     unlink <$tempDir/$name-src-*.log>;
  18.     unlink <$tempDir/$name-src-*.txt>;
  19.     unlink <$tempDir/$name-src-*.dvi>;
  20.     unlink <$tempDir/$name-src-*.ps>;
  21.     unlink <$tempDir/$name-src-*.pdf>;
  22.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

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

Re: Copiar bloques de texto en archivos separados

Notapor explorer » 2014-04-08 05:55 @288

Se pueden hacer un par de cosillas...

La primera y más inmediata: fíjate que en la exp. reg. usas tres paréntesis de captura, pero en realidad, solo te hacen falta dos: $1 y $2 los utilizas siempre juntos, así que te puedes ahorrar el tener que extraerlos de forma separada:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.         if ( $fich =~ /($name-src-\d+)($ext)/ ) {
  2.             system("latex $imageDir/$1$2");
  3.             system("dvips -Ppdf $tempDir/$1.dvi");
  4.             system("ps2pdf $tempDir/$1.ps");
  5.             system("pdfcrop -margins 1 $tempDir/$1.pdf $imageDir/$1.pdf");
  6.         }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Nota también que no es necesario "escapar" el '.' dentro de los literales entrecomillados dobles, porque... son literales, no son patrones de exp. reg.

Con un Perl moderno, se pueden dar nombres a las capturas, y así también no dependemos del orden en que han sido capturadas:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.         if ( $fich =~ /(?<nombre>$name-src-\d+)(?<extension>$ext)/ ) {
  2.             system("latex $imageDir/$+{nombre}$+{extension}");
  3.             system("dvips -Ppdf $tempDir/$+{nombre}.dvi");
  4.             system("ps2pdf $tempDir/$+{nombre}.ps");
  5.             system("pdfcrop -margins 1 $tempDir/$+{nombre}.pdf $imageDir/$+{nombre}.pdf");
  6.         }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Ya solo queda agregar un poco de aire:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.         if ( $fich =~ /(?<nombre>$name-src-\d+)(?<extension>$ext)/ ) {
  2.  
  3.             system("latex             $imageDir/$+{nombre}$+{extension}");
  4.             system("dvips -Ppdf        $tempDir/$+{nombre}.dvi");
  5.             system("ps2pdf             $tempDir/$+{nombre}.ps");
  6.             system("pdfcrop -margins 1 $tempDir/$+{nombre}.pdf    $imageDir/$+{nombre}.pdf");
  7.         }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


En cuanto al unlink(), si estás en un entorno Bash shell, puedes hacer algo como esto y sustituir todos los comandos por uno solo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     unlink <$tempDir/$name-src-*.{aux,log,txt,dvi,ps,pdf}>;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
(no es algo propio de Perl, sino de Bash).

Al final, quedaría así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $tempDir = ".";                     # directorio temporal
  2.  
  3. # Compilamos en forma individual cada fichero
  4. opendir(my $DIR, $imageDir) or die "ERROR: no puedo abrir directorio $imageDir: $!\n";
  5.  
  6. while (readdir $DIR) {
  7.     if (/(?<nombre>$name-src-\d+)(?<extension>$ext)/) {
  8.  
  9.         system("latex              $imageDir/$+{nombre}$+{extension}");
  10.         system("dvips -Ppdf         $tempDir/$+{nombre}.dvi");
  11.         system("ps2pdf              $tempDir/$+{nombre}.ps");
  12.         system("pdfcrop -margins 1  $tempDir/$+{nombre}.pdf    $imageDir/$+{nombre}.pdf");
  13.     }
  14. }
  15.  
  16. closedir $DIR;
  17.  
  18. unlink <$tempDir/$name-src-*.{aux,log,txt,dvi,ps,pdf}>;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
(Hemos quitado $fich, porque puede usarse $_, en su lugar. El código queda más corto y limpio).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Copiar bloques de texto en archivos separados

Notapor pablgonz » 2014-04-08 07:44 @364

Genial, tomaré en cuenta lo de capturar solo lo que necesito, la verdad es que dividir en tres no era necesario. Lo de usar nombres para las capturas es bastante cómodo y fácil de recordar, en fin, tu código es más corto y conciso, revisaré lo de unlink()... me ahorraré bastantes líneas.

Agradecido,
Pablo.
PD: La línea:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. unlink <$tempDir/$name-src-*.{aux,log,txt,dvi,ps,pdf}>;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
también funciona en win7.
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Anterior

Volver a Básico

¿Quién está conectado?

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

cron