Perl

從多個文件複製特定數據。然後生成一個包含多個數據的csv文件

  • October 14, 2016

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

這就是為什麼第一列應該只是剩下 5 列中具有 5 個 bor 值的單個 par 值。當我執行我的程式碼時,它會列印出我需要的所有來自 bor 和 par 的值,這些值位於使用 if 語句的這些文件的特定區域中。問題是它不會在我的輸出 .csv 文件中列印任何內容。它只列印最後一個 par 值和最後一個 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;

我認為您的具體問題(只有最後一個值出現在輸出文件中)是由$fh_res內部循環內以寫入模式打開引起的。打開文件有 3 種基本模式:讀取 ( '<')、寫入 ( '>') 和追加 ( '>>')。‘write’ 和 ‘append’ 之間的區別在於前者會丟棄所有現有內容,而使用 ‘append’ 會保留它們。

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

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

引用自:https://unix.stackexchange.com/questions/316345