從多個文件複製特定資料。然後產生一個包含多個資料的csv文件

從多個文件複製特定資料。然後產生一個包含多個資料的csv文件

您可以從我的程式碼中看到,我有兩個循環,因為每個面值有 5 個 bor 值。所以我有 50 個帶有輸出 .out 副檔名的檔案。因此,我使用兩個循環將文件自動輸入到程式碼中。我的目標是製作一個 .csv 文件,其中包含一列 1 個面值,以及從不同 bor 值文件中獲取的 5 列不同值,並且對於不同面值的行也是如此。對於這些組合中的每一個,我的面值對於所有5 個bor 值都保持不變,但是我的bor 值對於每個組合都會發生變化。 5 個不同bor 值的相同常數值,而第 2 列到第 6 列將具有不同的值,我將從這些檔案中取得這些值。

因此,第一列應該只是單一票面值,其餘 5 列有 5 個 bor 值。當我執行程式碼時,它會使用 if 語句從 bor 和 par 列印我需要的所有值,這些值位於這些檔案的特定區域中。問題是它不會在我的輸出 .csv 檔案中列印任何內容。它只是列印最後一個面值與最後一個 bor 值的組合值。本例為 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;

答案1

我認為您的特定問題(只有最後一個值出現在輸出檔案中)是由於$fh_res在內循環內以寫入模式開啟而引起的。開啟檔案有 3 種基本模式:讀 ( '<')、寫 ( '>') 和追加 ( '>>')。 「寫入」和「附加」之間的差異在於,使用前者會丟棄任何現有內容,而使用「附加」則保留它們。

在您的程式碼片段中,我建議在定義 .csv 檔案之後直接將用於定義 csv 檔案的檔案名稱和檔案句柄的行移到循環之外$file_in

如果這個片段實際上是真實事物的簡化版本,並且您有一些充分的理由在內部循環中打開和重新打開 csv 文件,那麼我認為您可以通過將模式'>'(write) 替換為'>>'(append )。

相關內容