替换写入文件描述符的最后一行
问题描述:
我正在写一个小的perl程序,我正在检查#start和#end的模式。议程是用开始和结束模式之间的线创建一个单独的文件。这我可以用下面的脚本来做。替换写入文件描述符的最后一行
#!/usr/bin/perl
open(INFILE,"<","testcases") || die "Can't open file: $!";
my $binary;
my $tccounter=1;
while(<INFILE>)
{
if(/^#start/i)
{
open(OUTFILE,">",$tccounter."_case.sh") || die "Can't open file: $!";
print "start of the script\n";
next;
}
elsif(/^#end/i)
{
################################
# Want to replace the previously
# written line here with some
# addtional customized lines
################################
close(OUTFILE);
$tccounter++;
print "End of the script\n";
print "last line for this testcase is \n $binary\n";
next;
}
else
{
$binary=$_ unless(/^\s*$/);
print OUTFILE $_;
}
}
但我还需要的是为确定被写入到文件的最后一行,然后替换一些自定义的数据,额外的线。 例如,在我的情况下,所有文件的最后一行是执行的。 我想在所有输出文件中替换“execute”行。 在电流输出文件的最后一行如下:
execute
有望走出文件的最后一行应该是
preline
execute
postline
输入文件(测试用例):
#start
line1
line 2
execute
#end
#start
line3
line 4
execute
#end
#start
line5
line 6
execute
#end
#start
line7
line 8
execute
#end
答
我建议你应该缓冲你的输出
如果你把每一行代替一个数组o f然后打印它,一旦看到#end
标签,就很容易找到阵列中的最后一个非空白行并替换它
然后可以打开输出文件并将其打印到数组的内容
下面是一个未经考验例如
use strict;
use warnings 'all';
open my $fh, "<", "testcases" or die "Can't open input file: $!";
my $n;
my $i;
my $print;
my @buff;
while (<$fh>) {
if (/^#start/i) {
@buff =();
$i = undef;
$print = 1;
print "start of the script\n";
}
elsif (/^#end/i) {
my $file = ++$n . "_case.sh";
$print = 0;
unless (defined $i) {
warn "No data found in block $n";
next;
}
splice @buff, $i, 1, "preline\n", $buff[$i], "postline\n";
open my $fh, ">", $file or die qq{Can't open "$file" for output: $!};
print $fh @buff;
close $fh;
print "End of the script\n";
}
elsif ($print) {
push @buff, $_;
$i = $#buff if /\S/;
}
}
答
重复使用触发器操作员无法抗拒并重写鲍罗丁解决方案:
我觉得Borodins答案是去(我只是无法尚未就此发表评论)的方式。
所以一般的算法是:
- 收集完整的记录,从开始标记结束标记
- 一旦达到结束标志,过程记录的内容。你的情况:
- 找到最后一个非空行,并与他人围绕着它
- 打印找到的行
- 需要
我写出来的文件记录
use strict;
use warnings;
open(my $in,'<','in.file') || die "Can't open file: $!";
my ($cnt,@rec);
while(<$in>) {
push(@rec,$_) if /^#start/i .. /^#end/i; # collect record lines (using flipflop operator)
if(/^#end/i) { # end of record reached?
next if @rec <= 2; # ignore empty records
# determine index of last nonempty line
my ($lci) = grep {$rec[$_]=~/\S/} reverse (1..$#rec-1); # ...except markers
printf "last line for this testcase is \n%s\n", # print find
splice @rec, $lci, 1, ("preline\n",$rec[$lci],"postline\n"); # surround with pre&post
# write out result
open(my $out,'>',++$cnt.'_case.sh') || die "Can't open file: $!";
$out->print(@rec[1..$#rec-1]); # ...except markers
$out->close;
@rec=(); # empty record for next use
}
}
*您必须*在您编写的每个Perl程序的顶部使用strict和'use warnings'all''。使用'my'来声明变量没有'use strict'就没有什么意义了。 – Borodin