• Publicidad

De tres archivos generar uno nuevo

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

De tres archivos generar uno nuevo

Notapor lis » 2009-04-02 21:50 @951

Hola amigos del foro. Les cuento mi situación: tengo 3 archivos separados para el mismo día, donde cada uno tiene distintas dimensiones; entonces lo que yo quiero hacer es que de esos tres archivos se elijan los que coinciden en la primera columna y los guarde en un cuarto archivo.

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

while($one=<*_ecmwf_cmoreno>) {
    $fecha=substr($one,0, 8 );
    open(UNO, "<$one");                        
    open(DOS, "<*_fh_cmoreno");
    open(TRES, "<*_sonda_cmoreno");
    $day="$fecha"."_tmp_cmoreno";
    open(CUATRO, ">$day");             #cuarto archivo.

    while( $uno = <UNO> ) {                    
        $dos = <DOS>;
        $tres = <TRES>;                        
        chomp($uno, $dos, $tres);                  
        @dato = split(" ", $uno);
        @data = split(" ", $dos);
        @date = split(" ", $tres);

        if ($dato[0]==1000 and $data[0]==1000 and $date[0]=1000) {
            print CUATRO "$dato[0] $dato[1] $data[1] $date[1]\n";
        }
        elsif ($dato[0]==850 and $data[0]==850 and $date[0]=850) {
            print CUATRO "$dato[0] $dato[1] $data[1] $date[1]\n";
        }
        elsif ($dato[0]==700 and $data[0]==700 and $date[0]=700) {
            print CUATRO "$dato[0] $dato[1] $data[1] $date[1]\n";
        }
        elsif ($dato[0]==500 and $data[0]==500 and $date[0]=500) {
            print CUATRO "$dato[0] $dato[1] $data[1] $date[1]\n";
        }
        elsif ($dato[0]==400 and $data[0]==400 and $date[0]=400) {
            print CUATRO "$dato[0] $dato[1] $data[1] $date[1]\n";
        }
        elsif ($dato[0]==300 and $data[0]==300 and $date[0]=300) {
            print CUATRO "$dato[0] $dato[1] $data[1] $date[1]\n";
        }
        elsif ($dato[0]==200 and $data[0]==200 and $date[0]=200) {
            print CUATRO "$dato[0] $dato[1] $data[1] $date[1]\n";
        }
        print CUATRO "$dato[0] $dato[1] $data[1] $date[1]\n";
    }

    elsif ($dato[0]==100 and $data[0]==100 and $date[0]=100) {
        print CUATRO "$dato[0] $dato[1] $data[1] $date[1]\n";
    }
}
}
close(UNO);                              
close(DOS);
close(TRES);
close(CUATRO);
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4


Lo único que me hace este script es crearme el cuarto archivo pero vacío.

Les pido su ayuda, muchísimas gracias de antemano.
lis
Perlero nuevo
Perlero nuevo
 
Mensajes: 106
Registrado: 2008-05-27 21:43 @946

Publicidad

Notapor danimera » 2009-04-03 00:16 @053

La solución es simple pero deberías poner la estructura de tus ficheros, para así poder hacer la corrección al problema,

Además no creo que puedas hacer un split() así
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
while( $uno = <UNO> ) {
$dos = <DOS>;  # AQUÍ ÉL DEVUELVE UN ARRAY DEL CONTENIDO DEL FICHERO, UN NUEVO ELEMENTO POR CADA SALTO DE LÍNEA, CREO
$tres = <TRES>;
chomp($uno, $dos, $tres);
@dato = split(" ", $uno);
@data = split(" ", $dos); # AQUÍ YA NO CREO QUE PUEDAS USAR split, YA QUE $dos no es un string...
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


No sé si me equivoqué pero deberías revisar eso mejor.
100% Telch - Perl Web Programming
Cali PerlMongers: http://cali.pm.org
Avatar de Usuario
danimera
Perlero frecuente
Perlero frecuente
 
Mensajes: 871
Registrado: 2005-06-23 19:02 @834
Ubicación: Colombia

Notapor explorer » 2009-04-03 06:58 @332

Hay errores en las comparaciones. Estás usando '=' cuando debería ser '=='.

Y el número de llaves de cierre... creo que no están bien compensadas...
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

Notapor creating021 » 2009-04-03 14:47 @657

danimera escribiste:La solución es simple pero deberías poner la estructura de tus ficheros, para así poder hacer la corrección al problema,

Además no creo que puedas hacer un split() así
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
while( $uno = <UNO> ) {
$dos = <DOS>;  # AQUÍ ÉL DEVUELVE UN ARRAY DEL CONTENIDO DEL FICHERO, UN NUEVO ELEMENTO POR CADA SALTO DE LÍNEA, CREO
$tres = <TRES>;
chomp($uno, $dos, $tres);
@dato = split(" ", $uno);
@data = split(" ", $dos); # AQUÍ YA NO CREO QUE PUEDAS USAR split, YA QUE $dos no es un string...
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


No sé si me equivoqué pero deberías revisar eso mejor.


Hay otro problema con esa solución, pues como bien dice lis:
lis escribiste:tengo 3 archivos separados para el mismo día, donde cada uno tiene distintas dimensiones;

Entonces, cuando <DOS> puede tener contenido, puede que <UNO> no lo tenga y que <TRES> sí tenga dentro de ese while (o problemas similares).
Además de eso, puede que la línea 100 de <UNO> cumpla con la 50 de <DOS> y la 1 de <TRES>.
Me gustaría dar una solución pero ahora no sé de ninguna :(
Expect the worst, is it the least you can do?
Avatar de Usuario
creating021
Perlero frecuente
Perlero frecuente
 
Mensajes: 595
Registrado: 2006-02-23 16:17 @720
Ubicación: Frente al monitor

Notapor danimera » 2009-04-03 18:36 @817

Dice diferentes dimensiones, entiendo diferentes líneas...
pero cómo se muestra la información en cada línea es lo que yo preguntaba.
100% Telch - Perl Web Programming
Cali PerlMongers: http://cali.pm.org
Avatar de Usuario
danimera
Perlero frecuente
Perlero frecuente
 
Mensajes: 871
Registrado: 2005-06-23 19:02 @834
Ubicación: Colombia

Notapor lis » 2009-04-03 20:40 @903

Hola amigos del foro: muchas gracias por su ayuda. Bueno, aquí están los tres archivos para el mismo día:

Este es 20081230_sonda_cmoreno:
Código: Seleccionar todo
1000   16.8   0.88   2.42
993   16.5   2.95   4.21
933   13.4  -1.53   1.38
925   15.4  -1.34   0.77
920   16.8  -1.36   0.72
910   17.2  -1.40   0.65
897   17.6  -1.44   0.55
858   16.0  -1.53   0.21
850   16.6  -1.54   0.13
804   16.8  -1.03   1.15
776   14.8  -0.25   1.00
761   15.8   0.02   1.03
738   14.3   0.43   0.93
707   12.2   0.32   2.03
700   12.8   0.22   2.56
697   13.2   0.09   2.57
660   10.6  -2.80   4.31
658   10.5  -2.95   4.21
636    9.0  -2.72   6.11
600    4.7  -0.85   9.74
532   -4.1  -2.80   1.30
526   -3.3  -2.43   0.84
524   -3.5  -2.46   0.75
506   -4.8  -0.51   0.00
501   -5.1  -0.51   0.04
500   -5.3  -0.51   0.04
490   -6.7  -1.03   0.00
458  -11.3   1.07  -3.98
453  -12.1   1.00  -3.99
400  -16.3   0.13  -1.54
397  -16.6   1.65  -1.97
396  -16.7   1.65  -1.97
390  -16.5   2.31  -2.76
375  -18.8   3.31  -3.94
350  -22.7   4.73  -4.73
349  -22.9   4.81  -4.65
336  -23.7   6.98  -5.26
308  -28.8  13.05  -4.75
300  -30.3  13.99  -6.52
268  -37.5  11.43  -9.59
257  -40.1  14.07  -9.49
250  -41.3  15.59  -9.00
245  -42.6  16.78  -7.83
234  -45.7  16.04  -8.17
227  -46.9  15.75  -8.73
208  -52.7  14.67  -9.53
201  -54.1  13.91  -9.74
200  -54.3  13.91  -9.74
189  -57.4  13.10 -13.10
188  -57.7  13.92 -12.98
184  -57.7  16.23 -11.79
178  -59.0  20.05  -9.35
176  -59.5  19.42  -8.24
173  -60.2  18.85  -6.86
153  -65.5  12.15  -6.73
150  -66.5  11.14  -6.43
149  -66.8  10.69  -6.17
146  -67.7   9.32  -4.35
135  -71.0  10.25  -0.90
133  -71.7   9.70   1.19
131  -71.9   8.22   2.99
126  -72.5   6.66  -0.58
120  -73.3   6.24   3.60
117  -72.0   0.76   8.71
116  -71.5  -0.31   8.74
112  -72.8  -4.37   7.57
105  -75.3  -6.66  -0.58
101  -76.7  -3.55  -0.63
100  -77.1  -2.80   1.30


Este es 20081230_ecmwf_cmoreno:

Código: Seleccionar todo
 1000 19.5770568847656 0.527821779251099 2.86659622192383
 925 17.4462280273438 -0.974200904369354 1.28270411491394
 850 16.3070068359375 0.151551619172096 -1.81671297550201
 700 11.7322387695312 -2.6105318069458 -0.754719972610474
 500 -5.39346313476562 -2.80920720100403 1.69020736217499
 400 -15.4523315429688 3.30399703979492 -5.29392337799072
 300 -30.1343383789062 11.7541847229004 -10.4658737182617
 200 -53.9481658935547 15.0551538467407 -14.4220542907715
 100 -77.255126953125 -3.03503060340881 1.33499264717102



Este es 20081230_fh_cmoreno:

Código: Seleccionar todo
 1000 24.50888061523438 0.8609685897827148 2.454782009124756
 850 18.37466430664062 0.06101134419441223 -1.037439107894897
 700 11.974609375 -1.701856851577759 1.649602055549622
 600 4.501434326171875 -2.099121809005737 3.796727657318115
 500 -5.23321533203125 -0.7169337272644043 3.405479431152344
 400 -16.0601806640625 3.223285675048828 -1.233854413032532
 300 -31.17556762695312 14.97671508789062 -4.939971446990967
 250 -41.01242065429688 15.30762481689453 -8.200047492980957
 200 -52.07179260253906 15.63027954101562 -11.43390274047852
 150 -66.32958984375 15.91667556762695 -6.861349105834961
 100 -76.96820068359375 -2.331923961639404 2.536499500274658
 70 -76.32113647460938 -9.62126636505127 4.996845722198486


Y lo que quería hacer es que de la primera columna de los 3 archivos que sean 1000, 850, 700, 500, 400, 300, 200 y 100 se guarden todos en un cuarto archivo claro con su respectiva fila.

Ojalás me puedan ayudar, muchas gracias.
lis
Perlero nuevo
Perlero nuevo
 
Mensajes: 106
Registrado: 2008-05-27 21:43 @946

Notapor explorer » 2009-04-04 05:49 @284

Esta es una de las muchas formas de resolverlo. He optado por la velocidad, usando diccionarios, en lugar de poner condiciones.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
$|=1;            # no caché

my $estacion = 'cmoreno';

## Bucle por todos los ficheros capturados
for my $fichero (<*_ecmwf_cmoreno>) {
    my $fecha = substr $fichero, 0, 8;

    print "Procesando fichero del día $fecha...\n";

    my $fichero_sonda  = $fecha . '_sonda_' . $estacion;
    my $fichero_ecmwf  = $fecha . '_ecmwf_' . $estacion;
    my $fichero_fh     = $fecha . '_fh_'    . $estacion;
    my $fichero_salida = $fecha . '_tmp_'   . $estacion;

    my %valores;


    ## Leemos los ficheros, indexados por la primera columna
    open SONDA, "<$fichero_sonda" or warn "ERROR: Fichero $fichero_sonda no encontrado: $!\n" and next;
    while (<SONDA>) {
        my @c = split;

        push @{$valores{$c[0]}}, @c[0,1];
    }
    close SONDA;

    open ECMWF, "<$fichero_ecmwf" or warn "ERROR: Fichero $fichero_ecmwf no encontrado: $!\n" and next;
    while (<ECMWF>) {
        my @c = split;

        push @{$valores{$c[0]}}, $c[1];
    }
    close ECMWF;


    open FH,    "<$fichero_fh"    or warn "ERROR: Fichero $fichero_fh no encontrado: $!\n"    and next;
    while (<FH>) {
        my @c = split;

        push @{$valores{$c[0]}}, $c[1];
    }
    close FH;

    #use Data::Dumper;
    #print Dumper \%valores;
    #exit;

    ## Escribimos el resultado
    open SALIDA, ">$fichero_salida" or die "ERROR: No puedo escribir en el fichero $fichero_salida: $!\n";
    for my $i ( 1000, 850, 700, 500, 400, 300, 200, 100 ) {

        if ( @{$valores{$i}} != 4 ) {
            warn "ERROR: Faltan valores para el valor $i\n";
            next;
        }

        print SALIDA join(' ', @{$valores{$i}}), "\n";
    }
    close SALIDA;
}
__END__
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Ha medida de que vamos leyendo los ficheros, vamos guardando los valores, en un arreglo que, a su vez, está guardado en un diccionario, indexado por el valor de la primera columna. Con eso obtenemos una estructura de datos así (recortado):
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$VAR1 = {
          '850' => [
                     '850',
                     '16.6',
                     '16.3070068359375',
                     '18.37466430664062'
                   ],
          '200' => [
                     '200',
                     '-54.3',
                     '-53.9481658935547',
                     '-52.07179260253906'
                   ],
          '500' => [
                     '500',
                     '-5.3',
                     '-5.39346313476562',
                     '-5.23321533203125'
                   ],
          '400' => [
                     '400',
                     '-16.3',
                     '-15.4523315429688',
                     '-16.0601806640625'
                   ],
          '700' => [
                     '700',
                     '12.8',
                     '11.7322387695312',
                     '11.974609375'
                   ],
          '100' => [
                     '100',
                     '-77.1',
                     '-77.255126953125',
                     '-76.96820068359375'
                   ],
          '300' => [
                     '300',
                     '-30.3',
                     '-30.1343383789062',
                     '-31.17556762695312'
                   ],
          '1000' => [
                      '1000',
                      '16.8',
                      '19.5770568847656',
                      '24.50888061523438'
                    ],
        };
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Ya solo queda imprimirlo por el orden que queramos.

Naturalmente, este programa solo funcionará bien si los 3 ficheros tienen todos los datos de los valores que nos interesan. Por eso hay un if() en el último bucle, para avisarnos. En cambio, si estamos completamente seguros que no va a haber fallos, entonces podemos quitarlo.

La salida es:
Código: Seleccionar todo
1000 16.8 19.5770568847656 24.50888061523438
850 16.6 16.3070068359375 18.37466430664062
700 12.8 11.7322387695312 11.974609375
500 -5.3 -5.39346313476562 -5.23321533203125
400 -16.3 -15.4523315429688 -16.0601806640625
300 -30.3 -30.1343383789062 -31.17556762695312
200 -54.3 -53.9481658935547 -52.07179260253906
100 -77.1 -77.255126953125 -76.96820068359375
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

Notapor lis » 2009-04-04 13:30 @604

Hola a todos. Muchísimas gracias, Explorer. ¡¡Como siempre genial y funciona de maravillas!!
lis
Perlero nuevo
Perlero nuevo
 
Mensajes: 106
Registrado: 2008-05-27 21:43 @946


Volver a Básico

¿Quién está conectado?

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

cron