2016-11-15 120 views
-1

我正在寫一個小的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 
+2

*您必須*在您編寫的每個Perl程序的頂部使用strict和'use warnings'all''。使用'my'來聲明變量沒有'use strict'就沒有什麼意義了。 – Borodin

回答

1

我建議你應該緩衝你的輸出

如果你把每一行代替一個數組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/; 
    } 
} 
0

我覺得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 
        } 
    }