我在Read Write模式下打开一个文件(+<)并遍历保存上一行的每一行。基于前一行我试图修改当前行似乎不起作用。
我的输入:我有一个学生哈希,其中包含姓名,地址和DOB。我有一个文件,其中学生信息放在开始(本地或国际)和结束标签之间。
请在下面找到我输入的txt文件:
+++++++++++++++++++++++++++ViSHWASCHOOL++++++++++++++++++++++++++
student database system.... xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
some text here.... filled with xxx
for school data security ++++++
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
/begin Local
Karen
""
mothername Mawna
fathername Gildixon
total_marks 400
percent 90% /end Local
/begin Local
John
""
fathername Alister
mothername Linda
total_marks 320
percent 72% /end Local
/begin Local
Katie
"24 lenin street florida us"
mothername Sandra
fathername Manwel
total_marks 450
percent 95% /end Local
/begin International
Boris
""
mothername laumra
fathername deaol
total_marks 490
percent 98% /end International
/begin International
hawo binco
"honko , china"
mothername ""
fathername ""
total_marks 500
percent 100% /end International
任务:现在我要做的是填写学生档案中的所有地址,在学生姓名后面找到空的“”。保留学生档案的所有空格和格式。 。
我的Perl代码:
use strict;
use warnings;
use Data::Dumper;
my %student_hash;
my $student_report = "StudentReport.csv";
%student_hash = (
'RollNummber1' => {
'studentname' => 'Boris',
'address' => ['Vietnam',
'local'
],
'DOB' => '5june2000'
},
'RollNummber2' => {
'studentname' => 'John',
'address' => [
'4th/floor',
'Culverdown/Street',
'WestHam',
'UK.',
],
'DOB' => '2feb2000'
},
'RollNummber3' => {
'studentname' => 'Karen',
'DOB' => '5march2000'
}
);
my $studentfile = "testfile.txt";
my @studenttype = ('International', 'Local');
foreach my $type (@studenttype) {
process_studentfile( $type, $studentfile );
}
print "\nStudent Files are now filled with addresses\n";
sub process_studentfile {
my $type = shift;
my $studentfile = shift;
open(my $file,'+<',$studentfile);
my $previous_line = "";
while(my $current_line = <$file>){
if($current_line =~ /""/) {
foreach my $key(%student_hash) {
foreach my $name(keys %{$student_hash{$key}}) {
if($previous_line =~ /$student_hash{$key}{'studentname'}/) {
print $file join(",",@{$student_hash{$key}->{address}});
}
}
}
$previous_line = $_;
}
}
close $file;
}
**注意:**我以不同的方式对此感到厌倦,但仍然无法完成任务。可以在不使用任何cpan模块的情况下帮助一些标准模块吗?
答案 0 :(得分:1)
在尝试重写的同时使用while ( <$fh> )
存在根本问题。因为while
正在根据分隔符$/
读取文件块。但文件在字节中工作。
来自perldoc open
:
您通常不能使用读写模式来更新文本文件,因为它们具有可变长度的记录。请参阅
perlrun
中的-i开关以获得更好的方法。
因此,如果你写一个不同的长度线,一切都有点麻烦。它对文本文件效果不佳,因为你有可变长度的“记录”。
您可以使用seek
浏览文件,但请记住,您实际上是在每个字节(字符)的基础上进行覆盖。
或者只是使用临时文件,并在完成后将其复制到源代码上。这就是-i
的作用。 (这也意味着您损坏数据的风险要低得多,因为如果出现问题,您可以优雅地拯救)