• Publicidad

Editar ficheros .dat en un solo .dat y por columnas

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

Re: Editar ficheros .dat en un solo .dat y por columnas

Notapor enric73 » 2012-04-04 14:03 @627

Gracias explorer, buenas noches :)

He mirado los apuntes para concatenarlo a la fecha con el operador '.'.
Y he escrito lo siguiente

# Ponemos la fecha
my $llarg = $tabla->length();
$tabla->row_set($llarg, {

1 => strftime('%Y%m%d' , localtime),
});
# Concatenamos el argumento hs con la fecha

my $llarg2= $llarg." ".$hs;
#print $hs\n;
$tabla->row_move($llarg2, 0);
------------------------------------------------------------------------
Pero me sale el siguiente comentario
Backslash found where operator expected at ./VentsdatDefinitiu.pl line 21, near "$hs\"
(Missing operator before \?)


$hs lo entro como argumento pero no me lo lee, lo he concatenado con la fecha pero no me aparece...

my $llarg2= $llarg." ".$hs;
enric73
Perlero nuevo
Perlero nuevo
 
Mensajes: 154
Registrado: 2012-03-16 06:27 @311

Publicidad

Re: Editar ficheros .dat en un solo .dat y por columnas

Notapor explorer » 2012-04-04 14:45 @656

No lo has puesto en el sitio correcto.

Lo has puesto en el sitio en que movemos la última fila, a la primera. Vamos, que no tiene nada que ver.

Debes concatenarlo con el strftime(), que es el que genera la fecha.
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: Editar ficheros .dat en un solo .dat y por columnas

Notapor enric73 » 2012-04-04 15:13 @675

¡Ya está, explorer! Gracias por la ayuda y paciencia.

# Ponemos la data y la hora simulación
my $llarg = $tabla->length();
$tabla->row_set($llarg, {

1 => strftime('%Y%m%d' , localtime)." ".$hs,
});

$tabla->row_move($llarg, 0);


20120404 000000
-6.37 3.75 -6.19 3.42 -6.17 3.56 -7.08 3.01 -6.81 2.98
-6.43 3.64 -6.24 3.31 -6.23 3.46 -7.13 2.89 -6.86 2.86
-6.49 3.53 -6.30 3.20 -6.29 3.35 -7.18 2.76 -6.91 2.74
-6.55 3.41 -6.36 3.09 -6.35 3.24 -7.22 2.64 -6.96 2.62
-6.61 3.30 -6.41 2.98 -6.40 3.12 -7.27 2.51 -7.00 2.50
-6.67 3.18 -6.46 2.86 -6.46 3.01 -7.31 2.38 -7.04 2.37
-6.72 3.06 -6.51 2.75 -6.51 2.90 -7.35 2.26 -7.08 2.25
-6.78 2.95 -6.56 2.64 -6.56 2.78 -7.39 2.13 -7.12 2.13
-6.83 2.83 -6.60 2.52 -6.60 2.67 -7.43 2.00 -7.16 2.00
-6.87 2.71 -6.64 2.41 -6.65 2.55 -7.46 1.87 -7.19 1.88
-6.92 2.59 -6.69 2.29 -6.69 2.44 -7.49 1.74 -7.22 1.75
-6.96 2.47 -6.72 2.17 -6.74 2.32 -7.52 1.61 -7.25 1.63
enric73
Perlero nuevo
Perlero nuevo
 
Mensajes: 154
Registrado: 2012-03-16 06:27 @311

Re: Editar ficheros .dat en un solo .dat y por columnas

Notapor enric73 » 2012-04-13 06:51 @327

Hola explorer,

Si en el caso tratado en este tema, de juntar los diferentes ficheros .dat de un directorio en uno solo pero en vez de juntarlos en diferentes columnas (como en el caso tratado en este tema) los tuviera que juntar todos en la misma columna, de un tirón, y alternados UGRD10m* y VGRD10m* y ordenados por hora (como es este caso), ¿podría aprovechar toda esta estructura?

Muchas gracias.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. # ----------------------------------------------------------------------------
  2. # Arguments del programa:  [yyyymmdd]hh hhmmss
  3. # ----------------------------------------------------------------------------
  4. if ( @ARGV != 2 ) {
  5.     us_programa();
  6. }
  7.  
  8. # Data
  9. chomp( $flag = $ARGV[0] );
  10.  
  11. # hora simulacio GFS
  12. chomp( $hs = $ARGV[1] );
  13.  
  14. #print "$flag"\n;
  15.  
  16. # Comprovem que els parametres siguin correctes
  17. if ( $flag =~ m/^(00|06|12|18)$/ ) {
  18.     $hh = $flag;
  19.     chomp( $yyyymmdd = `date +%Y%m%d` );
  20.     $yymmdd = substr( $yyyymmdd, 2, 6 );
  21.     $real_time = 1;
  22. }
  23. elsif ( $flag =~ m!^(19|20)\d\d(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])(00|06|12|18)$! ) {
  24.     $yyyymmdd = substr( $flag,     0, 8 );
  25.     $yymmdd   = substr( $yyyymmdd, 2, 6 );
  26.     $hh       = substr( $flag,     8, 2 );
  27.     $real_time = 0;
  28. }
  29. else {
  30.     us_programa();
  31. }
  32.  
  33. my @arxius_U = </home/enric/v2.22/ASCII/$flag/UGRD10m*.dat>;
  34. my @arxius_V = </home/enricc/v2.22/ASCII/$flag/VGRD10m*.dat>;
  35. @arxius_U = ordenados_por_hora(@arxius_U);
  36. @arxius_V = ordenados_por_hora(@arxius_V);
  37.  
  38. sub ordenados_por_hora {
  39.     my $x;
  40.  
  41.     map      { $_->[1] }
  42.         sort { $a->[0] <=> $b->[0] }
  43.         map {
  44.         ($x) = $_ =~ /10m(\d+)/;
  45.         [ $x, $_ ];
  46.         } @_;
  47. }
  48.  
  49. print "[", join( "][", @arxius_U ), "]\n";
  50. print "[", join( "][", @arxius_V ), "]\n";
  51.  
  52. my @arxius = zip @arxius_U, @arxius_V;
  53. my $tabla = Data::CTable->new();
  54.  
  55. # {
  56. for my $i ( 1 .. @arxius ) {
  57.     my $col = Data::CTable->new;
  58.  
  59.     $col->read(
  60.         _FileName    => $arxius[ $i - 1 ],
  61.         _HeaderRow   => 0,
  62.         _FieldList   => [$i],
  63.         _CacheOnRead => 0,
  64.     );
  65.  
  66.     $col->row_delete(0);
  67.  
  68.     $tabla->combine($col);
  69.  
  70. }
  71.  
  72. for my $i ( 1 .. @arxius ) {
  73.     my @indexs = @{ $tabla->all() };
  74.     my $files  = $tabla->col($i);
  75.  
  76.     my $ample_maxim = 0;
  77.  
  78.     for my $j (@indexs) {
  79.  
  80.         my $valor = $files->[$j] // '';
  81.  
  82.         my $ample = length $valor;
  83.  
  84.         if ( $ample_maxim < $ample ) {
  85.             $ample_maxim = $ample;
  86.         }
  87.     }
  88.  
  89.     for my $j (@indexs) {
  90.         $files->[$j] = sprintf "%*.2f", $ample_maxim, $files->[$j] // 0;
  91.  
  92.     }
  93.  
  94. }
  95.  
  96. ## Posem la data
  97. my $llarg = $tabla->length();
  98. $tabla->row_set(
  99.     $llarg,
  100.     {
  101.  
  102.         1 => strftime( '%Y%m%d', localtime ) . " " . $hs,
  103.     }
  104. );
  105.  
  106. $tabla->row_move( $llarg, 0 );
  107.  
  108. #   my $hs = $tabla->length();
  109. #   $tabla->row_set($hs, {
  110.  
  111. #       1 => $hs,
  112. #  });
  113. # $tabla->row_move($hs, 0);
  114.  
  115. # Sortida
  116. chdir("/home/enric/v2.22/ASCII/vents.dat/");
  117. $tabla->write(
  118.     _FileName   => 'vents.dat',
  119.     _FDelimiter => "\t",
  120.     _HeaderRow  => 0,
  121. );
  122.  
  123. # Eliminar fitxers temporals
  124. chdir("/home/enric/v2.22/scripts/");
  125. @files = qw( Ventsdat.pl~ VENT_GFStoWWW300.pl~ VENT_GFStoWWW312.pl~ );
  126. foreach $file (@files) {
  127.     unlink($file);
  128. }
  129.  
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4
Última edición por explorer el 2012-04-13 12:19 @554, editado 1 vez en total
Razón: Formateado de código con Perltidy
enric73
Perlero nuevo
Perlero nuevo
 
Mensajes: 154
Registrado: 2012-03-16 06:27 @311

Re: Editar ficheros .dat en un solo .dat y por columnas

Notapor explorer » 2012-04-13 12:30 @562

Sería aún más sencillo: no nos haría falta el módulo Data::CTable ni ninguna de las líneas en las que intervienen sus funciones y métodos.

Bastaría con leer por pares los ficheros, metiendo los datos en arrays, y luego con el zip de List::MoreUtils, se haría la mezcla.
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: Editar ficheros .dat en un solo .dat y por columnas

Notapor enric73 » 2012-04-15 06:23 @308

Hola explorer,

Estoy un poco atascado con el tema. Pongo el código en Perl.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.     use v5.10; 
  3.     use POSIX 'strftime';
  4.     use Class::Date qw(date now);
  5.     use List::MoreUtils 'zip';
  6.  
  7. my @archivos_U =  </home/enric/ASCII/2012041400/UGRD10m*.dat>;
  8. my @archivos_V =  </home/enric/ASCII/2012041400/VGRD10m*.dat>;
  9.  
  10. $i=0;
  11. foreach $archivos_U (@archivos_U) {
  12.         print "leyendo ", $archivos_U,"\n";
  13.         @uval = ();
  14.         open(ARCHI_U,"$archivos_U[$i];
  15.        while(<ARCHI_V>) {
  16.         chomp;
  17.         $val = sprintf("%.2f", $_);
  18.         open(ARCHI_V,"$archivos_V[$i];
  19.         chomp;
  20.         $val1 = sprintf("%.2f", $_);
  21.         push(@uval, $val,$val1);
  22.         }
  23. $i++;
  24. #my @archivos = zip @archivos_U, @archivos_V;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


En el programa intento leer los archivos U y V a pares y luego meterlos por orden en un fichero .dat en una simple columna. No sé si de esta manera, con este bucle voy bien.

¿Alguien puede ayudarme? Gracias. Buen fin de semana.
enric73
Perlero nuevo
Perlero nuevo
 
Mensajes: 154
Registrado: 2012-03-16 06:27 @311

Re: Editar ficheros .dat en un solo .dat y por columnas

Notapor explorer » 2012-04-15 08:10 @382

Fíjate en los colores que esta propia página está poniendo a tu código: Te está mostrando que te faltan unas comillas dobles ;)

Tienes desordenadas las órdenes de open() y lectura de los archivos. Por ejemplo, en la línea 14 abres ARCHI_U, pero en la línea siguiente estás leyendo desde ARCHI_V.

Lo mejor es leer todo de golpe (usar la memoria), leer por pares con each_array(), formatear, y sacar todo.

Algo así (no probado):
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use v5.10;
  3. use POSIX 'strftime';
  4. #use Class::Date qw(date now);
  5. use List::MoreUtils qw<zip each_array>;
  6. use autodie;
  7.  
  8. my @archivos_U = </home/enric/ASCII/2012041400/UGRD10m*.dat>;
  9. my @archivos_V = </home/enric/ASCII/2012041400/VGRD10m*.dat>;
  10.  
  11. die "ERROR: No coinciden el número de archivos U y V.\n"
  12.     if @archivos_U != @archivos_V;
  13.  
  14. # Aquí falta ordenar los archivos por hora
  15.  
  16.  
  17. # Proceso
  18. my @dat;
  19.  
  20. my $ea_archivos = each_array(@archivos_U, @archivos_V);
  21.  
  22. while ( my( $archivo_u, $archivo_v ) = $ea_archivos->() ) {
  23.  
  24.     # Abrimos archivos
  25.     open my $U, '<', $archivo_u;
  26.     open my $V, '<', $archivo_v;
  27.  
  28.     # Leemos archivos
  29.     my @u = <$U>;
  30.     my @v = <$V>;
  31.  
  32.     # Comprobación
  33.     die "ERROR: No tienen el mismo número de líneas los archivos $archivos_U[$i] y $archivos[$i]."
  34.         if @u != @v;
  35.  
  36.     # Cerramos archivos
  37.     close $U;
  38.     close $V;
  39.  
  40.     # Mezcla
  41.     my $ea_cols = each_array(@u, @v);
  42.  
  43.     while( my($u, $v) = $ea_cols->() ) {
  44.         push @dat, sprintf"%.2f %.2f", $u, $v;
  45.     }
  46. }
  47. __END__
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: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Editar ficheros .dat en un solo .dat y por columnas

Notapor enric73 » 2012-04-15 15:51 @702

Gracias explorer, unas consultas sobre el código.
1.-
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $ea_archivos = each_array(@archivos_U, @archivos_V);
  2.  
  3. while ( my( $archivo_u, $archivo_v ) = $ea_archivos->() ) {
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
¿Con qué identifica la primera línea el escalar? ¿Exactamente qué conseguimos con esta línea? ¿Y la siguiente?

2.- Intento guardar el resultado en un fichero de salida, lo creo, pero los datos no se guardan bien, adjunto el fichero entero y las lineas añadidas para ver dónde tengo el error.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  #!/usr/bin/perl
  2.     use v5.10;
  3.     use POSIX 'strftime';
  4.     #use Class::Date qw(date now);
  5.     use List::MoreUtils qw<zip each_array>;
  6.     use autodie;
  7.      
  8.     my @archivos_U = </home/enric/ASCII/2012041400/UGRD10m*.dat>;
  9.     my @archivos_V = </home/enric/ASCII/2012041400/VGRD10m*.dat>;
  10.      
  11.     die "ERROR: No coinciden el número de archivos U y V.\n"
  12.         if @archivos_U != @archivos_V;
  13.      
  14.     # Aquí falta ordenar los archivos por hora
  15.      
  16.      
  17.     # Proceso
  18.     my @dat;
  19.      
  20.     my $ea_archivos = each_array(@archivos_U, @archivos_V);
  21.      
  22.     while ( my( $archivo_u, $archivo_v ) = $ea_archivos->() ) {
  23.      
  24.         # Abrimos archivos
  25.         open my $U, '<', $archivo_u;
  26.         open my $V, '<', $archivo_v;
  27.      
  28.         # Leemos archivos
  29.         my @u = <$U>;
  30.         my @v = <$V>;
  31.      
  32.         # Comprobación
  33.         die "ERROR: No tienen el mismo número de líneas los archivos $archivos_U[$i] y $archivos[$i]."
  34.             if @u != @v;
  35.      
  36.         # Cerramos archivos
  37.         close $U;
  38.         close $V;
  39.      
  40.         # Mezcla
  41.         my $ea_cols = each_array(@u, @v);
  42.      
  43.         while( my($u, $v) = $ea_cols->() ) {
  44.             push @dat, sprintf"%.2f %.2f", $u, $v;
  45.          print "leyendo ", @dat,"\n";
  46.         }
  47.     }
  48.        $file = "ventscol.dat";
  49.         open( DATA, ">$file");
  50.         print DATA @dat;
  51.         close DATA;
  52.     __END__
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


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

Re: Editar ficheros .dat en un solo .dat y por columnas

Notapor explorer » 2012-04-15 20:16 @886

1.- each_array() crea un "iterador" y lo guarda en $ea_archivos. La misión de un iterador es la de devolvernos un elemento distinto, de una serie de elementos, cada vez que lo llamamos. En el bucle while() ejecutamos ese iterador, que nos devuelve un elemento de cada array (de ahí le viene el nombre: each_array) cada vez que se le llama. $archivo_u almacenará cada vez un elemento del array @archivos_U, y $archivo_v hará lo mismo con el @archivos_V.

Es una forma cómoda de sacar valores de los array de forma secuencial y simultánea.

2.- Cuando haces print DATA @dat; Perl despliega los contenidos de @dat, tal cual son. ¿Y cuales son? Pues según lo construimos en la línea 44: cadenas de caracteres SIN RETORNO DE CARRO. Por esa salen todas juntas.

Modifica el sprintf de esa línea agregando un "\n" a la cadena de formato. O modifica la forma de imprimir hacia el archivo, haciendo un bucle, por ejemplo, haciendo un print de cada elemento de @dat, con su "\n" correspondiente.
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: Editar ficheros .dat en un solo .dat y por columnas

Notapor enric73 » 2012-04-16 03:03 @168

Buenos días, explorer.

Al final he añadido "\n" al print():
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. print DATA "@dat, \n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

En todo caso, ¿cómo modificaría el sprintf() de esa línea agregando un "\n" a la cadena de formato? ¿O cómo modificaría la forma de imprimir hacia el archivo, haciendo un bucle, por ejemplo, haciendo un print() de cada elemento de @dat, con su "\n" correspondiente?

He visto que de esta manera se intercalan los datos cada dos ficheros (U y V). Pero lo quiero más sencillo. Primero que se guarden los datos del fichero U (todos seguidos), luego los del fichero V (todos seguidos) para una cierta hora pero sin intercalar los datos del fichero U y V, luego otra vez todos los datos de los ficheros U y V para la siguiente hora... ¿En este caso el each_array() no lo necesitaría?

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

AnteriorSiguiente

Volver a Básico

¿Quién está conectado?

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