Copie datos específicos de varios archivos. Luego genere un archivo csv con múltiples datos.

Copie datos específicos de varios archivos. Luego genere un archivo csv con múltiples datos.

Como puede ver en mi código, tengo dos bucles porque para cada valor nominal hay 5 valores bor. entonces tengo 50 archivos con la extensión de salida .out. Así que estoy usando dos bucles para introducir los archivos en el código automáticamente. Mi objetivo es crear un archivo .csv que tenga una columna de 1 valor nominal y 5 columnas de diferentes valores que tomo de diferentes archivos de valores bor, y eso continúa para filas de diferentes valores nominales. Para cada una de estas combinaciones, mi valor nominal permanece constante para los 5 valores de bor, pero mi valor de bor cambia para cada combinación. Entonces, necesito 6 columnas en cada fila, la columna uno tendría el mismo valor constante de los 5 valores de bor diferentes, y La columna 2 a la columna 6 tendrá valores diferentes que tomaré de esos archivos.

Es por eso que la columna uno debe ser solo el valor nominal único con 5 valores bor en las 5 columnas restantes. Cuando ejecuto mi código, me imprime todos los valores que necesito de bor y par, que se encuentran en áreas específicas de esos archivos usando la declaración if. El problema es que no imprime nada en mi archivo .csv de salida. Simplemente imprime los valores de la combinación del último valor nominal con el último valor nominal. que en este caso es 1,3500

    #!/usr/bin/perl

    # the strict package forces you to declare each variable you use beforehand
    use strict;

    # a variable in strict mode is declared using my
    # the $ symbol means it is a single-valued variable
    # the @ symbol means it is an array
    # each declaration/instruction is closed with a ; sign 

    my @par_list = (0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1);
    #bor is my boron concentration list
    my @bor_list = (0,800,1600,2500,3500);
    # creating a variable for the current value of the parameter
    my $value;
    my $value_2;
    # get and store the size of the array
    my $nbr_of_values = $#par_list;
    my $nbr_of_values_2 = $#bor_list;
    # now, we read in a variable that will be the filename of the template input file
    # $ARGV are the input arguments, 0 means it is the first one (perl starts counting at 0, not 1)
    my $file_in = $ARGV[0];

    # start of the loop
    for( my $i=0; $i<= $nbr_of_values; $i++){
        #create another loop for boron values and assign a letter j to it
        for ( my $j=0; $j<= $nbr_of_values_2; $j++){
        $value_2 = $bor_list[$j];
            $value = $par_list[$i];
            print "This is the current parameter value: $value \n";

            # now we create a new string variable that will later be the filename of the new input deck
            # the . symbol is the concatenation operator between strings
            my $new_output_filename = $file_in."file_in_".$value."_".$value_2.".out";
            print " The new filename is $new_output_filename \n";
            my $result_filename = $file_in."_".".csv";

            # open the template file and store its filehandle (fh_in)
            open my $fh_out,  '<', $new_output_filename or die "Can't open output $new_output_filename !";
            # open the new file (it currently does not exist and is thus empty) and store its filehandle (fh_out)
            open my $fh_res, '>', $result_filename or die "Can't open output $result_filename !";

            while (<$fh_out>) {
            # this is for you to see on the console, we read line-by-line, while there is something
            # the line read is stored in a special PERL variable $_
            # now we actually print that line into the new file
            # BUT BEFORE THAT, we change the dummy characters for the real value
            # we use a regular expression (read the tutorials for more details_
            # s = substitute
                if ((/ COO /)&& (/                     INPUT/)) {
                print "found burnup $_ ";
                my @array = split(/\s+/,$_);
                #print "the bu value is $array[3] \n";
                print $fh_res "$array[2] ,";
                }
                if ((/   K-INF /) && (/M2 =/)) {
                print "found kinf $_ ";

                #print "the bu value is $array[3] \n";
                print $fh_res "$array[7] ,";
                }

            }
            close $fh_out; 
            close $fh_res;

         }
    }

    print " I am done with this !!! \n";
    exit 111;

Respuesta1

Creo que su problema específico (solo aparece el último valor en el archivo de salida) se debe a la apertura $fh_resen modo de escritura dentro del bucle interno. Hay 3 modos básicos para abrir un archivo: leer ( '<'), escribir ( '>') y agregar ( '>>'). La diferencia entre 'escribir' y 'añadir' es que con el primero se descarta cualquier contenido existente, mientras que con 'añadir' se conservan.

En su fragmento, sugeriría mover las líneas para definir el nombre del archivo y el identificador del archivo csv fuera de los bucles, directamente después de definir $file_in.

Si este fragmento es en realidad una versión simplificada del original y tiene buenas razones para abrir y volver a abrir el archivo csv dentro del bucle interno, entonces creo que puede resolver su problema reemplazando el modo '>'(escribir) por '>>'(agregar ).

información relacionada