• Publicidad

Manipulación ficheros planos

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

Manipulación ficheros planos

Notapor enric73 » 2013-05-06 14:47 @658

Hola, gente. Consulta: tengo dos ficheros txt. Los junto. Luego quiero añadir una primera fila en el nuevo fichero con el nombre de Canarias Finisterre. Me parece que el código queda demasiado largo, y tampoco me quedan alienadas las columnas con el nombre que añado en cada una de ellas.

Cada fichero original contiene una columna de 4 números:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
0.57
0.70
0.90
1.15
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


El resultado:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Canarias Finisterre
0.87 0.57
0.87 0.70
0.85 0.90
0.80 1.15
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Realmente me gustaría que la columna de números que corresponde a Finisterre estuviera alineada, debajo justo de Finisterre. En resumen, una columna bien hecha.

El código:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl

open(UN, "<alturaolascanarias.txt"); # Abrir...
open(DOS, "<alturaolasFinisterre.txt");
open(OUT, ">alturaolas.dat");

while( $u = <UN> ) {   # Leemos del primer fichero
    $dos = <DOS>;         # Leemos del segundo
    chomp($u, $dos);    
    print OUT "$u $dos \n";
}

close(UN);                
close(DOS);
close(OUT);

use Tie::File;
     
tie my @fichero, 'Tie::File', 'alturaolas.dat' or die "ERROR: No se pude enlazar con el fichero: $!\n";
     
    splice @fichero, 0, 0, 'Canarias Finisterre';  # Insertar una línea al principio
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Saludos y gracias
Última edición por explorer el 2013-05-06 17:27 @769, editado 1 vez en total
Razón: Marcas de código Perl
enric73
Perlero nuevo
Perlero nuevo
 
Mensajes: 154
Registrado: 2012-03-16 06:27 @311

Publicidad

Re: manipulacion ficheros planos

Notapor Skaraluk » 2013-05-06 16:14 @718

¿Qué tal, enric73?

Basándome en tu código creo que ésto se aproxima a lo que necesitas:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. open(AOC, "<alturaolascanarias.txt");
  4. open(AOF, "<alturaolasFinisterre.txt");
  5. open(OUT, ">alturaolas.dat");
  6.  
  7. @AOC = <AOC>; #Guardo archivos en Arrays
  8. @AOF = <AOF>;
  9.  
  10. for ($i=0;$i<scalar(@AOC);$i++){ #Hago un for desde 0 hasta el largo del primer archivo
  11.     if ($i==0){
  12.         print OUT "Canarias Finisterre\n"; #Si es la primera línea inserto Canarias Finisterre con un salto de línea
  13.     }
  14.     $AOC[$i] =~ s/\t|\n| //gsi; #Elimino tabulaciones, saltos de linea y espacios de la línea del primer txt
  15.     $AOF[$i] =~ s/\t|\n| //gsi; #Elimino tabulaciones, saltos de linea y espacios de la línea del segundo txt
  16.     print OUT $AOC[$i]." ".$AOF[$i].$/; #Imprimo en archivo de destino con un salto de línea al final
  17. }
  18. close AOC;
  19. close AOF;
  20. close OUT;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¡Saludos!
Avatar de Usuario
Skaraluk
Perlero nuevo
Perlero nuevo
 
Mensajes: 3
Registrado: 2013-05-03 15:56 @705

Re: Manipulación ficheros planos

Notapor explorer » 2013-05-06 20:18 @887

Recordar que esto también lo puede hacer el comando paste del sistema operativo, desde el shell.

Si suponemos que los archivos de texto tienen el mismo número de líneas, se puede hacer también de esta manera:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5. use autodie;
  6.  
  7. open my $AOC, '<', 'alturaolascanarias.txt';
  8. open my $AOF, '<', 'alturaolasFinisterre.txt';
  9. open my $OUT, '>', 'alturaolas.dat';
  10.  
  11. print $OUT join("\t", qw( Canarias Finisterre)), "\n";   # cabecera
  12.  
  13. while (my $col1 = <$AOC>) {
  14.     chomp $col1;
  15.     my $col2 = <$AOF>;                                   # no quitamos el "\n" de esta columna, por ser la última
  16.  
  17.     print $OUT join("\t", $col1, $col2);
  18. }
  19.  
  20. close $AOC;
  21. close $AOF;
  22. close $OUT;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Naturalmente, esto es para solo dos columnas. Si es para más, entonces hay que adoptar otra estrategia más general.
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: Manipulación ficheros planos

Notapor enric73 » 2013-05-07 10:47 @491

¡Muchas gracias a los dos!

He añadido una columna más, una tercera, adaptando vuestros códigos. Y me ha funcionado también. Mi pregunta es. Si en vez de tener 3 ficheros, tengo 10, ¿hay alguna manera de cogerlos todos a la vez, sabiendo que tienen el mismo número de filas? ¿con un glob()? Y también añadiendo a la primera fila, un nombre para cada columna, 10 nombres.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.      
  3. open(AOC, "<alturaolascanarias.txt");
  4. open(AOF, "<alturaolasFinisterre.txt");
  5. open(AOCAN, "<alturaolasCantabrico.txt");
  6. open(OUT, ">alturaolas.dat");
  7.      
  8. @AOC = <AOC>; #Guardo archivos en Arrays
  9. @AOF = <AOF>;
  10. @AOCAN = <AOCAN>;
  11.    
  12. for ($i=0;$i<scalar(@AOC);$i++){ #Hago un for desde 0 hasta el largo del primer archivo
  13. if ($i==0){
  14. print OUT "Canarias Finisterre Cantabrico\n"; #Si es la primera línea inserto Canarias Finisterre con un salto de línea
  15. }
  16. $AOC[$i] =~ s/\t|\n| //gsi; #Elimino tabulaciones, saltos de línea y espacios de la línea del primer txt
  17. $AOF[$i] =~ s/\t|\n| //gsi; #Elimino tabulaciones, saltos de línea y espacios de la línea del segundo txt
  18. $AOCAN[$i] =~ s/\t|\n| //gsi; #Elimino tabulaciones, saltos de línea y espacios de la línea del segundo txt
  19. print OUT $AOC[$i]."     ".$AOF[$i]."     ".$AOCAN[$i].$/; #Imprimo en archivo de destino con un salto de línea al final
  20. }
  21. close AOC;
  22. close AOF;
  23. close AOCAN;
  24. close OUT;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4



Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5. use autodie;
  6.      
  7. open my $AOC, '<', 'alturaolascanarias.txt';
  8. open my $AOF, '<', 'alturaolasFinisterre.txt';
  9. open my $AOCAN, '<', 'alturaolasCantabrico.txt';
  10. open my $OUT, '>', 'alturaolas.dat';
  11.      
  12. print $OUT join("\t", qw( Canarias Finisterre Cantabrico)), "\n";   # cabecera
  13.      
  14. while (my $col1 = <$AOC>) {
  15. chomp $col1;
  16. my $col2 = <$AOF>;
  17. chomp $col2;
  18. my $col3 = <$AOCAN>;                                  # no quitamos el "\n" de esta columna, por ser la última
  19.      
  20. print $OUT join("            ", $col1, $col2, $col3);
  21. }
  22.    
  23. close $AOC;
  24. close $AOF;
  25. close $AOCAN;
  26. close $OUT;
  27.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Resultado:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Canarias     Finisterre     Cantabrico
0.87               0.57           0.70
0.87               0.70           0.67
0.85               0.90           0.66
0.80               1.15           0.70
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Gracias a los dos
Última edición por explorer el 2013-05-07 11:05 @503, editado 1 vez en total
Razón: linea => línea
enric73
Perlero nuevo
Perlero nuevo
 
Mensajes: 154
Registrado: 2012-03-16 06:27 @311

Re: Manipulación ficheros planos

Notapor explorer » 2013-05-07 11:08 @505

Se podrían indicar el nombre de los archivos a unir como argumentos al programa, que podríamos leer sus nombres a partir de la variable @ARGV.

Solo quedaría hacer los bucles correspondientes.

Pero antes hay que resolver de dónde sacamos los titulares de esos diez archivos. ¿De otro 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: Manipulación ficheros planos

Notapor enric73 » 2013-05-07 12:03 @544

Hola, explorer,

¿Se puede sacar el titular de los 14 archivos del propio nombre de cada archivo? He reducido el nombre de los archivos. Ahora, en vez de alturaolas, etc.,... directamente pongo Finisterre.txt, Cantabrico.txt, Canarias.txt, Azores.txt, SanVicente.txt, Cadiz.txt, Madeira.txt, GranSol.txt, Gibraltar.txt, Alboran.txt, Palos.txt, Baleares.txt, GolfoValencia.txt, Leon.txt.

Cada archivo tiene una columna de 4 números, todos son iguales en ese sentido.

¿O hacer un print más largo?

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. print $OUT join("\t", qw( Canarias Finisterre Cantabrico Azores SanVicente Cadiz Madeira  GranSol Gibraltar Alboran Palos Baleares GolfoValencia Leon)), "\n";   # cabecera
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


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

Re: Manipulación ficheros planos

Notapor explorer » 2013-05-07 13:02 @585

Es fácil sacar los nombres de los archivos, usando una expresión regular, o función substr(), por ejemplo.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5. use feature 'say';
  6. use autodie;
  7.  
  8. @ARGV or die "Uso: $0 <archivo.txt> [... <archivo.txt>]\n";
  9.  
  10. #my @cabeceras = map { m/^(.+?)[.]...$/ } @ARGV;    # le quitamos la extensión de tres letras
  11. my @cabeceras = map { substr $_, 0, -4 } @ARGV;    # hace lo mismo: quita los últimos 4 caracteres
  12.  
  13. ## Abrimos los archivos
  14. my @fh;
  15. for my $i (0 .. $#ARGV) {
  16.     open $fh[$i], '<', $ARGV[$i];
  17. }
  18.  
  19. ## Abrimos archivo de salida
  20. open my $OUT, '>', 'alturaolas.dat';
  21.  
  22. ## Cabecera
  23. say $OUT join "\t", @cabeceras;
  24.  
  25. ## Bucle
  26. while (not eof $fh[0]) {
  27.     my @columnas = map { scalar <$_> } @fh;      # leemos una línea (scalar) por cada archivo en @fh
  28.     chomp @columnas;
  29.  
  30.     say $OUT join "\t", @columnas;
  31. }
  32.  
  33. ## Cerramos
  34. close $_ for @fh, $OUT;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
Esto está probado, y funciona.

Ahora bien, ahora dices que los archivos tienen 4 columnas... Eso es nuevo. ¿Cómo son esas columnas? ¿Hay que separarlas igual que a las otras?
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: Manipulación ficheros planos

Notapor enric73 » 2013-05-07 14:14 @635

Gracias, explorer,

Tengo un pequeñito problema, no encuentra feature.pm. ¿Qué librería puedo instalarme con CPAN para que encuentre el feature.pm?
Os copio la salida en la consola, cuando he ejecutado el script perl...

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
  1. bash-3.2$ ./onades3.pl
  2. Can't locate feature.pm in @INC (@INC contains: /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl /usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/5.8.8 .) at ./onades3.pl line 5.
  3. BEGIN failed--compilation aborted at ./onades3.pl line 5 (#1)
  4.     (F) You said to do (or require, or use) a file that couldn't be
  5.     found. Perl looks for the file in all the locations mentioned in @INC,
  6.     unless the file name included the full path to the file.  Perhaps you
  7.     need to set the PERL5LIB or PERL5OPT environment variable to say where
  8.     the extra library is, or maybe the script needs to add the library name
  9.     to @INC.  Or maybe you just misspelled the name of the file.  See
  10.     perlfunc/require and lib.
  11.    
  12. Uncaught exception from user code:
  13.         Can't locate feature.pm in @INC (@INC contains: /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl /usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/5.8.8 .) at ./onades3.pl line 5.
  14. BEGIN failed--compilation aborted at ./onades3.pl line 5.
  15.  at ./onades3.pl line 5.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
enric73
Perlero nuevo
Perlero nuevo
 
Mensajes: 154
Registrado: 2012-03-16 06:27 @311

Re: Manipulación ficheros planos

Notapor enric73 » 2013-05-07 18:00 @791

Hola, explorer.

He instalado una versión más actualizada del Perl. La versión que tenía estaba un poco desfasada: perl v5.8, y por esta razón (supongo) no podía instalar feature.pm. Ahora, sí que carga feature "say". Me sale un error, al ejecutar el código que me has preparado anteriormente,

Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
  1. [enric@localhost perl]$ ./onades3.pl
  2. Use of uninitialized value $fh[0] in ref-to-glob cast at ./onades3.pl line 24 (#1)
  3.     (W uninitialized) An undefined value was used as if it were already
  4.     defined.  It was interpreted as a "" or a 0, but maybe it was a mistake.
  5.     To suppress this warning assign a defined value to your variables.
  6.    
  7.     To help you figure out what was undefined, perl will try to tell you the
  8.     name of the variable (if any) that was undefined. In some cases it cannot
  9.     do this, so it also tells you what operation you used the undefined value
  10.     in.  Note, however, that perl optimizes your program and the operation
  11.     displayed in the warning may not necessarily appear literally in your
  12.     program.  For example, "that $foo" is usually optimized into "that "
  13.     . $foo, and the warning will refer to the concatenation (.) operator,
  14.     even though there is no . in your program.
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


¿A que crees que es debido? ¿Dónde se selecciona los ficheros .txt?

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

Re: Manipulación ficheros planos

Notapor explorer » 2013-05-07 19:48 @867

Efectivamente, el error del 'feature' era por tener una versión de Perl muy antigua.

El error que sale luego es debido a que no has pasado ningún archivo como argumento al programa.

Debes ejecutar tu programa así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
  1. ./onades3.pl Canarias.txt Finisterre.txt Cantabrico.txt Azores.txt SanVicente.txt Cadiz.txt Madeira.txt GranSol.txt Gibraltar.txt Alboran.txt Palos.txt Baleares.txt GolfoValencia.txt Leon.txt
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

He reeditado el programa para añadirle la línea 8, con lo que sale un mensaje indicando la forma de usar el programa, en caso de que se vuelva a llamar sin argumentos.
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

Siguiente

Volver a Básico

¿Quién está conectado?

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