
Wie Sie meinem Code entnehmen können, habe ich zwei Schleifen, da es für jeden Par-Wert fünf Bor-Werte gibt. Ich habe also 50 Dateien mit der Ausgabeerweiterung .out. Ich verwende also zwei Schleifen, um die Dateien automatisch in den Code einzuspeisen. Mein Ziel ist es, eine CSV-Datei zu erstellen, die eine Spalte mit einem Par-Wert und fünf Spalten mit unterschiedlichen Werten enthält, die ich aus Dateien mit unterschiedlichen Bor-Werten nehme, und das geht so weiter für Zeilen mit unterschiedlichen Par-Werten. Für jede dieser Kombinationen bleibt mein Par-Wert für alle 5 Bor-Werte konstant, aber mein Bor-Wert ändert sich für jede Kombination. Ich brauche also 6 Spalten in jeder Zeile, Spalte 1 hätte den gleichen konstanten Wert aller 5 verschiedenen Bor-Werte und Spalte 2 bis Spalte 6 hätten unterschiedliche Werte, die ich aus diesen Dateien nehme.
Deshalb sollte Spalte eins nur der einzelne Par-Wert mit 5 Bor-Werten in den verbleibenden 5 Spalten sein. Wenn ich meinen Code ausführe, druckt er mir alle Werte aus Bor und Par aus, die ich brauche und die sich in bestimmten Bereichen dieser Dateien befinden, und zwar mit der if-Anweisung. Das Problem ist, dass in meiner Ausgabe-CSV-Datei nichts gedruckt wird. Es werden nur die Werte der Kombination aus dem letzten Par-Wert und dem letzten Bor-Wert gedruckt. Das ist in diesem Fall 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;
Antwort1
Ich denke, dass Ihr spezielles Problem (nur der letzte Wert erscheint in der Ausgabedatei) durch das Öffnen $fh_res
im Schreibmodus innerhalb der inneren Schleife verursacht wird. Es gibt 3 grundlegende Modi zum Öffnen einer Datei: Lesen ( '<'
), Schreiben ( '>'
) und Anhängen ( '>>'
). Der Unterschied zwischen „Schreiben“ und „Anhängen“ besteht darin, dass Sie beim ersten alle vorhandenen Inhalte verwerfen, während sie beim „Anhängen“ erhalten bleiben.
Ich würde in Deinem Snippet vorschlagen, die Zeilen zur Definition des Dateinamens und des Dateihandles der CSV-Datei außerhalb der Schleifen direkt nach der Definition zu verschieben $file_in
.
Wenn dieser Codeausschnitt tatsächlich eine vereinfachte Version des Originals ist und Sie gute Gründe dafür haben, die CSV-Datei innerhalb der inneren Schleife zu öffnen und erneut zu öffnen, dann können Sie Ihr Problem meiner Meinung nach lösen, indem Sie den Modus '>'
(Schreiben) durch '>>'
(Anhängen) ersetzen.