3

入力ファイル:

{test test
{***********************************************************************
{Rtest
{***********************************************************************
{test
{***********************************************************************
{* date
{*
{* Initial revision
{*
{***********************************************************************

{output}

{output1}

{output 2}

{Test TEst TEST}  
{Test test test}

{*********************}

{********************}

必要な出力:

{Output}
{output1}
{output2}

脚本

use strict;
use warnings;

while (<DATA>) {
  $line = $_;
  chomp $line;

  push( @lines, $line );

  $line =~ s/^\s+//;
  $line =~ s/\s+$//;

  for ( my $i = 0 ; $i <= $#lines ; $i++ ) {
    if ( $lines[$i] =~ m/(^{\**$)/ ) {

      push( @matched, $lines[ $i + 1 ] );
      print "$lines[$i+1]"."\n";
    }
  }
}

私の出力:

 {test test
    {***********************************************************************
    {Rtest
    {***********************************************************************
    {test
    {***********************************************************************
    {* date
    {*
    {* Initial revision
    {*
    {***********************************************************************

一番上のブロックを一致させることはできますが、必要な最初の 3 行を出力として取得できません。上記の一致条件から、次の行を抽出しようとしていますが、出力として空白が表示されます。何か足りないものがありますか、よろしくお願いします。

4

3 に答える 3

3

更新:最後の編集後、OP が目的の出力を変更したため、この回答は無効になりました。

これは非常に簡単に行うことができます。カーリーで始まるすべての行と{空の行を削除するだけです。

use strict; use warnings;
use Data::Dumper;
my @output;
while (<DATA>) {
  chomp;           # remove newline
  next if /^\{\*/; # We don't want lines starting with an open curly and an asterisk
  next if /^\s*$/; # We also do not want lines that are empty
  push @output, $_;
}

print Dumper \@output;

出力:

$VAR1 = [
          'output',
          'output1',
          'output 2'
        ];
于 2012-07-17T07:29:53.017 に答える
3

このプログラムは、あなたが望むかもしれないものについての私の最善の推測です. コマンドラインで入力ファイルが必要です。

で始まる行の後に、空白ではない次の 3 行を出力するように記述しました{*。しかし、どのルールが行を除外するかはわかりません

{Rtest

{test

しかし、あなたが欲しいと言うものを含めてください。さらに何か必要な場合は、もう一度お尋ねください。

アップデート

?で終わる行だけを印刷したいかもしれません。}代わりにそれを行うようにコードを変更しました

use strict;
use warnings;

my @lines;
my @matched;

my $n = 0;

while (<>) {
  if ( /^\s*\{\*+/ ) {
    $n = 3;
  }
  elsif ( $n and /\}\s*$/ ) {
    print;
    $n-- ;
  }
}

出力

{output}
{output1}
{output 2}
于 2012-07-17T11:00:55.157 に答える
0

なぜあなたが行のバックログに戻って繰り返しそれらを@matched押し込むのかわかりません-特に、あなたが得ようとしていると言う出力と一致しない場合. これはもっとうまくいく...

while ( <DATA> ) { 
    print if m/^[{]o/i;
}

'{Output}'or'{output2}'のみ'{output}'に対応する入力行がないため、指定した出力が得られない'{output 2}'ため、単に仕様が雑ではない場合に備えて、修正する必要があるかもしれません。

while ( <DATA> ) { 
    next unless my ( $n ) = m/^[{]output\s*(\d)?[}]/i;
    my $output = length $n ? 'output' : 'Output';
    say "{$output$n}";
}
于 2012-07-17T12:45:59.547 に答える