제 코드를 보면 각 단위마다 5개의 bor 값이 있기 때문에 두 개의 루프가 있다는 것을 알 수 있습니다. 그래서 출력 확장자가 .out인 파일이 50개 있습니다. 그래서 두 개의 루프를 사용하여 파일을 코드에 자동으로 공급합니다. 내 목표는 1개 단위의 열과 다른 bor 값 파일에서 가져온 다른 값의 5개 열을 포함하고 다른 단위의 행에 대해 동일한 .csv 파일을 만드는 것입니다. 이러한 각 조합에 대해 내 액면가는 5개의 bor 값 모두에서 동일하게 유지되지만 내 bor 값은 각 조합에 대해 변경됩니다. 따라서 행당 6개의 열이 필요합니다. 첫 번째 열은 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
내부 루프 내에서 쓰기 모드로 열면 특정 문제(출력 파일에 마지막 값만 나타남)가 발생한 것 같습니다 . 파일을 여는 데에는 읽기( '<'
), 쓰기( '>'
) 및 추가( ) 의 세 가지 기본 모드가 있습니다 '>>'
. "쓰기"와 "추가"의 차이점은 전자를 사용하면 기존 콘텐츠가 모두 삭제되는 반면 "추가"를 사용하면 해당 콘텐츠가 유지된다는 점입니다.
코드 조각에서 .csv 파일을 정의한 직후에 csv 파일의 파일 이름과 파일 핸들을 정의하는 줄을 루프 외부로 이동하는 것이 좋습니다 $file_in
.
이 조각이 실제로 실제의 단순화된 버전이고 내부 루프에서 csv 파일을 열고 다시 열어야 하는 타당한 이유가 있는 경우 패턴 '>'
(쓰기) 을 '>>'
(추가)로 바꾸면 그렇게 할 수 있다고 생각합니다.