• Publicidad

Llamar un Perl one-liner desde un programa en Perl

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

Llamar un Perl one-liner desde un programa en Perl

Notapor Alfumao » 2012-05-14 04:42 @237

Buenos días a todos.

He escrito un programa de Perl que llama a un "one-liner" para llevar a cabo una operación (eliminar todas las lineas que empiecen por "@" de un fichero de texto de un tamaño muy grande, varios Gigabytes).
Pero me dá el siguiente error al llamar al "one-liner":

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Use of uninitialized value in concatenation (.) or string at samcleanser.pl line 23.
syntax error at -e line 1, near "="
Execution of -e aborted due to compilation errors.
 
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Este es el código:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!usr/bin/perl -w
  2. use strict;
  3.  
  4. #usage samcleanser.pl [full dir path]
  5. #print "Enter your directory path:\n"; #carpeta
  6. #chomp(my $path = <STDIN>);
  7.  
  8. my $path = shift @ARGV;
  9. print "$path\n";
  10. chdir $path or die "ERROR: Unable to enter $path: $!\n";
  11. opendir( TEMP, "." );
  12. my @files = readdir(TEMP);
  13. closedir TEMP;
  14.  
  15. for my $file (@files) {
  16.  
  17.     if ( $file =~ /(\w+\.\w+).sam/ ) {
  18.  
  19.         my $name = $1;
  20.  
  21.         print "cleaning $name\.sam\n";
  22.  
  23.         my $clean = `perl -pi -e '$_="" if (/^@/)' $name`;
  24.     }
  25. }
  26.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


¿Se puede hacer la llamada que yo he intentado, en Perl?

Una pregunta más: ¿podría hacerse más rápido usando bash?

Gracias de antemano por vuestra atención.
Alfumao
Perlero nuevo
Perlero nuevo
 
Mensajes: 178
Registrado: 2009-12-10 11:20 @514

Publicidad

Re: Llamar un Perl one-liner desde un programa en Perl

Notapor explorer » 2012-05-14 05:49 @284

No sé muy bien dónde puede estar el error... podrían ser los últimos paréntesis, o la mezcla de comillas en el one-liner.

De todas maneras... ¿por qué haces eso? Estás ejecutando un proceso Perl por cada archivo que quieres modificar... eso es muy ineficiente...

Mira... con unos pequeños cambios, lo tienes resuelto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!usr/bin/perl
  2. # usage samcleanser.pl [full dir path]
  3. # Alfumao, 2012.
  4.  
  5. use v5.10;
  6. use strict;
  7. use warnings;
  8. use autodie;    # «Mejor morir que regresar con deshonor» --Proberbio Kinglon
  9.  
  10. # print "Enter your directory path:\n"; #carpeta
  11. # chomp(my $path = <STDIN>);
  12.  
  13. my $path = shift @ARGV;
  14. say $path;
  15.  
  16. chdir $path;
  17.  
  18. opendir(TEMP, "." );
  19.  
  20. while (my $file = readdir TEMP) {
  21.  
  22.     if (my($name) = $file =~ /(\w+[.]\w+[.]sam)/ ) {
  23.  
  24.         say "cleaning $name";
  25.  
  26.         open my $FI, '<',  $name;
  27.         open my $FO, '>', "$name.part";
  28.  
  29.         while (my $linea = <$FI>) {
  30.             next if '@' eq substr $linea, 0, 1; # no ponemos la línea si el primer carácter es '@'
  31.             print $FO $linea;
  32.         }
  33.        
  34.         close $FI;
  35.         close $FO;
  36.        
  37.         rename "$name.part", $name;             # rename cambia el nombre y sobreescribe el original
  38.     }
  39. }
  40.  
  41. closedir TEMP;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Este programa realiza la misma función, pero es mucho más rápido, ya que no ejecuta un nuevo proceso por cada archivo. Y las operaciones que realiza son las mismas que con el operador -i: abre un archivo nuevo donde va guardando los cambios y al final hace un rename() para dejar solo con el nombre original (bueno, no es exactamente así el orden en que -i funciona, pero las operaciones son las mismas).

En cuanto a si es más rápido hacerlo con Bash... pues yo sospecho que los tiempos serán los mismos, ya que las operaciones serán las mismas, y dependemos del cuello de botella que marca el sistema de ficheros.

Eso sí, el programa en Bash quedará más largo (mucho más) si intentas imitar las operaciones que hace este programa. Solo fíjate en la cantidad de código que autodie nos ahorra...
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: Llamar un Perl one-liner desde un programa en Perl

Notapor Alfumao » 2012-05-14 07:45 @364

Muchísimas gracias, explorer.

Lo probaré en cuanto pueda. El único problema es que estoy trabajando sobre servidores remotos (no tengo permisos allí) y la versión de Perl que tienen es 5.8... Además no sé si tienen instalados los módulos que requiere tu código.

De todas formas merece la pena probarlo, porque estoy seguro que es muy rápido.

:D
Alfumao
Perlero nuevo
Perlero nuevo
 
Mensajes: 178
Registrado: 2009-12-10 11:20 @514

Re: Llamar un Perl one-liner desde un programa en Perl

Notapor explorer » 2012-05-14 10:14 @468

Quita las líneas 5 y 8.
Sustituye los say() por print() más un retorno de carro al final.
Agrega ' or die "ERROR: No se pudo abrir el archivo: $!\n"; ' al lado de cada open() y chdir()
(incluso habría que hacerlo con los print() y close(), que es lo que hace autodie, pero no hace falta tanto miramiento).

Y ya está.
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: Llamar un Perl one-liner desde un programa en Perl

Notapor Alfumao » 2012-05-29 09:47 @449

Muchas gracias, explorer, por la respuesta.

Tengo una pregunta, ¿cómo podría hacer funcionar este "one-liner" (que posteaste en su día) en varios archivos a la vez?
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. perl -p -i -e 's/\r//' script.pl
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Así funciona sobre por ejemplo un script de Perl, ¿cómo se escribiría para modificar todos los archivos Perl de un mismo directorio?

¿Así?
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. perl -p -i -e 's/\r//' *.pl
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

¿Y si queremos incluir un directorio diferente del que estamos al escribir el "one-liner", ¿cómo se introduce el directorio en el "one-liner"?

Gracias de nuevo.
Alfumao
Perlero nuevo
Perlero nuevo
 
Mensajes: 178
Registrado: 2009-12-10 11:20 @514

Re: Llamar un Perl one-liner desde un programa en Perl

Notapor explorer » 2012-05-29 11:53 @536

Sí, se haría de esa manera, con *.pl

Y para indicar un subdirectorio, pues en la parte de argumentos:

/ruta/al/directorio/*.pl

Más ejemplos, en perldoc perlrun
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: Llamar un Perl one-liner desde un programa en Perl

Notapor Alfumao » 2012-05-30 08:17 @386

¡¡¡Muchas gracias, explorer!!!

;)
Alfumao
Perlero nuevo
Perlero nuevo
 
Mensajes: 178
Registrado: 2009-12-10 11:20 @514


Volver a Básico

¿Quién está conectado?

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