2012-07-17 24 views
3

輸入文件:如何在匹配perl文本後提取所需的行?

{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行作爲輸出。從上面的匹配條件我試圖提取下一行,但我得到一個空白的輸出。 我錯過了什麼,在此先感謝。

+2

你的代碼不能和'use strict'一起使用。有很多'需要顯式包名'錯誤。另外,你已經重新定義了'$ line'。 – simbabque 2012-07-17 07:25:45

+1

如果你寫下你的'輸出'行匹配的特定條件,這將非常有幫助。現在,正如我所看到的,它可以是'/^\ {[^ {] *} $ /'pattern'匹配的文件中的前三行,或者是與其他行由空字符串組成,不包含'*'符號。它不應該是這樣的:我們不需要討論你想要的東西。 – raina77ow 2012-07-17 09:03:59

+0

我同意@ raina77ow – quinekxi 2012-07-17 09:17:32

回答

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' 
     ]; 
+0

sinbabque:感謝您的輸出,但是我編輯了需要將大括號合併在一起的請求輸出,因爲我們無法跳過它們。 – Anil 2012-07-17 07:48:30

+2

或者只是'egrep -v'^($ | \ {\ *)'文件' – tripleee 2012-07-17 07:54:48

+0

@tripleee:我喜歡那個!但這裏不需要'\ *'。有些行像輸入中的'{test',OP不想輸出。 – simbabque 2012-07-17 08:01:27

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} 
+0

至少你的作品。 =) – simbabque 2012-07-17 13:57:49

0

我不知道爲什麼你通過線積壓回去,反覆推搡他們到@matched - 特別是當他們沒有匹配你說你想要得到的輸出。這樣做會更好...

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

,但它並不能達到您指定的輸出,因爲沒有相應於'{Output}''{output2}''{output}''{output 2}'沒有輸入線,所以,以防萬一它不只是草率的規範,我們可能需要修改它。

while (<DATA>) { 
    next unless my ($n) = m/^[{]output\s*(\d)?[}]/i; 
    my $output = length $n ? 'output' : 'Output'; 
    say "{$output$n}"; 
} 
相關問題