0

実行したサイクル数をログ ファイルに出力し続けるプログラムがあります。ログ ファイルの最後の値を取得して、実行されたサイクルの合計数を確認したいと考えています。私は次のコードを使用しています:

my @cycles = $log =~ /\s+(\d+)\s+Cycles/gsm;
$run{cycles} = $cycles[-1] if @cycles;

配列にサイクルを収集する代わりにそれを使用できるように、最後に一致した値を格納する perl の特別な変数はありますか?

4

5 に答える 5

1

これがあなたが望むものだと思います:

my @cycles = $log =~ /\s+(\d+)\s+Cycles/gsm;
$run{cycles} = $+ if @cycles;

squiguyが言ったように、それもうまくいく$1はずです(少なくとも私にとってはうまくいきます)。

最後に、すべてのサイクルを配列に保存する必要はなく、最後の値だけが必要な場合は、次のようにすることができます。

($run{cycles}) = $log =~ /.+\s(\d+)\s+Cycles/s;
于 2013-03-14T18:26:52.267 に答える
1

否定先読みアサーションを使用できます。

($run{cycles}) = $log =~ /\s+(\d+)\s+Cycles(?!.*\s+\d+\s+Cycles)/gsm;

意味は、「前に空白があり、その後に空白とリテラルが続く一連の数字を見つけ、その後Cyclesに空白、数字、空白、およびリテラルの別のシーケンスが続かないCycles」.

于 2013-03-14T17:51:22.397 に答える
1

ログファイル全体をメモリに読み込むことはお勧めしませんが、何をしているのかについての情報がなければ、適切な行ごとの解決策を書くことはできません.

修飾子を含む正規表現パターンは次の/g一致で停止するため、必要なのはループだけです。while

/mまたは/s修飾子を使用しても意味がないことに注意してください。これらは、メタ文字の機能を変更するだけなので^$および.. これらのどれも使用していないため、効果はありません。

while ( $log =~ /\s+(\d+)\s+Cycles/g ) {
    $run{cycles} = $1;
}
于 2013-03-14T18:32:37.367 に答える
0

あなたの質問は不完全です。ログファイルを $log に丸呑みするコードの部分は表示されていません。ログ ファイルの名前が $logFile にあると仮定すると、質問は改善方法です。

my $log = do { local( @ARGV, $/ ) = $logFile ; <> } ;
my @cycles = $log =~ /\s+(\d+)\s+Cycles/gsm;
$run{cycles} = $cycles[-1] if @cycles;

答えは、一度に 1 行ずつログ ファイルを読み取ることです。

open my $logFH,'<',$logFile
  or die "Could not open $logFile: $!";

my $cycles;
while (my $logLine = <$logFH>) {
    ($cycles) = $logLine =~ /\s+(\d+)\s+Cycles/;
}
close $logFH;

$run{cycles} = $cycles
  if $cycles;

このようにして、プログラムはファイル全体のスペースではなく $logFile の最長行のスペースのみを使用し、すべての代わりに単一のサイクルを格納するスペースを使用します。

つまり、I/O の量は同じですが、メモリ使用量ははるかに少なくなります。

元のプログラムは次のとおりです。

  1. ログファイルを開き、ログファイルの内容全体を丸呑みし、ログファイルを閉じます
  2. ログに記録されたすべてのサイクルを見つける
  3. もしあれば、ログに記録された最後のサイクルを使用します

このプログラムは次のとおりです。

  1. ログファイルを開く
  2. 一度に 1 行ずつログ ファイルを読み取る
    • 最後に見たサイクルを記憶する
  3. ログファイルを閉じる
  4. もしあれば、最後に確認されたサイクルを使用します
于 2013-03-14T18:27:37.997 に答える
0

File::ReadBackwards「最初の」一致する行を使用して取得しないのはなぜですか。

$bw = File::ReadBackwards->new( 'log_file' ) 
    or die "can't read 'log_file' $!" 
    ;
while( defined( $log_line = $bw->readline ) ) {
    next unless m/\s+(\d+)\s+Cycles/;
    print;
    last;
}

それはずっと速くなるはずです。

于 2013-03-14T21:16:57.840 に答える