2016-11-15 10 views
-1

私は#startと#endのパターンをチェックしている小さなperlプログラムを書いています。アジェンダは、開始パターンと終了パターンの間の線で別々のファイルを作成することです。これは私が以下のスクリプトで行うことができます。ファイルデリミッタに書き込まれた最後の行を置き換えます。

しかし、さらに必要なのは、ファイルに書き込まれている最後の行を特定し、その追加行をカスタムデータで置き換えることです。 たとえば、私の場合、すべてのファイルの最終行が実行されます。 すべての出力ファイルで "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プログラムの先頭に '厳密に'と '警告を使う 'ことが必須*です。 'use strict'を使わずに' my'を使って変数を宣言することはほとんどありません。 – Borodin

答えて

1

私はあなたのことを示唆しています出力をバッファする必要があります

代わりに各行を配列にプッシュすると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の答えが進むべき道だと思います。

ので、一般的なアルゴリズムは次のとおりです。

  • エンドマーカーは、プロセスレコードの内容を達すると、マーカー
  • を終了するには、開始マーカーから、完全なレコードを収集します。あなたのケースでは:
  • 印刷が

Iを必要に応じてレコードの

  • 繰り返しをファイルを書き出すライン
  • を見つけ
    • は、最後の非空行を見つけ、他の人とそれを囲みますフリップフロップ演算子を使用して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 
          } 
      } 
      
  • 関連する問題