2013-05-06 87 views
0

我的文件看起來像這樣:如何在Perl中匹配一行後抓取多行?

1 15 
2 16 
3 18 
4 19 
5 25 
6 30 
7 55 
8 45 
9 34 
10 52 

如果匹配圖案是30線6,我想抓住前N行和M行的第6行之後,例如,如果N = 3和M = 4所以結果預計是這樣的:

3 18 
4 19 
5 25 
6 30 
7 55 
8 45 
9 34 
10 52 

我是一個非常新的Perl初學者,任何意見將不勝感激。

#UPDATE 非常感謝以下這些有用的建議,我非常感謝他們。 這是我更新的代碼,歡迎任何建議!

my $num; 

while(<>) 
{ 
if (/pattern/) 
{$num = $. ;} 
} 

open (,"") || die ("Can't open the file"); 

while(<>) 

{ 
if ( $. >= $num-N and $. <=$num+M) 
{  
print OUT "$_ \r"; 
} 
} 
+2

是否可以在彼此的4行內找到兩個匹配項?如果是這樣,那麼是什麼? – ikegami 2013-05-06 02:54:19

+0

除非您將此作爲學習練習,否則您可能會考慮ack或grep:'ack'30'--before-context 3 - 之後上下文4 DATA_FILE'。 – FMc 2013-05-06 03:18:55

+0

@FMc非常感謝您對ack和grep的建議,並非常感謝。這只是我在Perl上的學習練習。 – Sam 2013-05-06 12:41:55

回答

1

保持一個數組(我稱之爲@preceding)的最後N線讀取。當模式匹配時,停止更新此數組並開始將行插入另一個數組(@following)。直到@followingM行爲止。

它應該是這個樣子(現在固定由於池上):

my $matched = 0; 
my @preceding; 
my @following; 
while(<>){ 
    if ($matched){ 
     push (@following, $_); 
     last if @following == M; 
     next; 
    } 
    else { 
     push (@preceding, $_); 
     shift(@preceding) if @preceding > N; 
    } 
    $matched = 1 if /pattern/; 
} 
+0

非常感謝。但是,我仍然無法使用上面的代碼打印我需要的數據... :(我稍後會嘗試使用 – Sam 2013-05-06 12:44:22

+0

@Sam如果您需要打印它,只需打印上一個和下一個的內容 – 2013-05-06 17:56:54

0
my @lines = <>; 
foreach $idx (grep { $lines[$_] =~ /pattern/ } 0..$#lines) { 
    print join (map {$lines[$_]} grep { $_ >= $idx - $B && $_ <= $idx +$A } 0..$#lines)."\n"; 
} 

您也可以使用GNU grep命令,用A,-B標誌爲確切的目的。

-A NUM, --after-context=NUM 
      Print NUM lines of trailing context after matching lines. 
      Places a line containing -- between contiguous groups of 
      matches. 

    -B NUM, --before-context=NUM 
      Print NUM lines of leading context before matching lines. 
      Places a line containing -- between contiguous groups of 
      matches. 
+0

非常感謝這給了我一個建設性和有益的想法!真的很感謝! – Sam 2013-05-06 12:46:08

相關問題