Copie dados específicos de vários arquivos. Em seguida, produza um arquivo csv com vários dados

Copie dados específicos de vários arquivos. Em seguida, produza um arquivo csv com vários dados

Como você pode ver no meu código, tenho dois loops porque para cada valor nominal existem 5 valores bor. então tenho 50 arquivos com a extensão .out de saída. Então, estou usando dois loops para alimentar os arquivos no código automaticamente. Meu objetivo é fazer um arquivo .csv que tenha uma coluna de 1 valor nominal e 5 colunas de valores diferentes que eu pego de arquivos de valores bor diferentes, e isso continua para linhas de valores pares diferentes. Para cada uma dessas combinações, meu valor nominal permanece constante para todos os 5 valores de bor, mas meu valor de bor muda para cada combinação. Portanto, preciso de 6 colunas em cada linha, a coluna um teria o mesmo valor constante de todos os 5 valores de bor diferentes e a coluna 2 à coluna 6 terá valores diferentes que pegarei desses arquivos.

É por isso que a coluna um deve ser apenas o valor nominal único com 5 valores bor nas 5 colunas restantes. Quando executo meu código, ele imprime todos os valores necessários de bor e par, que estão em áreas específicas desses arquivos usando a instrução if. O problema é que não imprime nada no meu arquivo .csv de saída. Apenas imprime os valores da combinação do último valor nominal com o último valor bor. que neste caso é 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;

Responder1

Acho que o seu problema específico (apenas o último valor aparece no arquivo de saída) é causado pela abertura $fh_resno modo de gravação dentro do loop interno. Existem 3 modos básicos para abrir um arquivo: leitura ( '<'), gravação ( '>') e acréscimo ( '>>'). A diferença entre 'write' e 'append' é que com o primeiro você descarta qualquer conteúdo existente enquanto com 'append' eles são mantidos.

No seu trecho, sugiro mover as linhas para definir o nome do arquivo e o identificador do arquivo csv fora dos loops, diretamente após a definição $file_in.

Se este trecho for realmente uma versão simplificada da versão real e você tiver alguns bons motivos para abrir e reabrir o arquivo csv dentro do loop interno, então acho que você pode resolver seu problema substituindo o modo '>'(gravação) por '>>'(anexar ).

informação relacionada