2009-06-15 79 views
3

我正在讀取輸入文件(IN)的每一行,並且如果行以模式之一開始,例如「ab」,「cd」,「ef」,「 gh「,」ij「等。打印的行格式爲」pattern:100「或格式」pattern:100:200「。我需要用「myPattern」替換「pattern」,即將當前行打印到FILE,但將第一次出現「:」前的所有文本替換爲「myPattern」。做這個的最好方式是什麼?如何在Perl替換之前替換匹配之前的所有文本?

目前我有:

while (<IN>) 
{ 
    print FILE if /^ab:|^bc:|^ef:|^gh:/; 
} 

我不知道如果SUBSTR置換將有助於爲「模式」可以是「AB」或「CD」或「EF」或「GH」等

謝謝! 默認碧

+0

你能舉一個例子,看看前後的樣子嗎? – YGA 2009-06-15 20:27:33

+1

輸出示例: BEFORE 均值:100 AFTER 方差:100 或 前 通道數據:50 AFTER 頻道頻率:50個 謝謝! – 2009-06-15 20:31:51

回答

0
sub replacer { 

    $line = shift; 
    $find = shift; 
    $replace = shift; 

    $line =~ /([^:]+):/ 
    if ($1 =~ /$find/) { 
     $line =~ s/([^:]+):/$replace/ ; 
     return $line;  
    } 
    return ; 

} 

while (<IN>) 
{ 
    print OUT replacer ($_,"mean","variance"); 
    print OUT replacer ($_,"pattern","newPattern"); 
} 

我的Perl是有點生疏,所以語法可能不準確。

編輯:把它放在一個函數爲雅。

0
while (<IN>) 
{ 
    s/^pattern:/myPattern:/; 
    print OUT 
} 
+0

無論它是否與第一個模式匹配,都會打印每一行。當我讀到原始問題時,只有匹配的行應該轉換並寫入OUT – 2009-06-15 20:37:23

1

Perl的替換操作(一)使用的第一場比賽,(b)只更換一個匹配和(c)如果進行了替換和虛假的,如果不是,則返回true。

所以:

while (<IN>) 
{ 
    if (s/<pattern1>:/<replace1>/ || 
     s/<pattern2>:/<replace2>/) { 
     print FILE; 
    } 
} 

應該爲你工作。請注意,由於短路,只能進行一次替換。

+0

請注意,您將剝離第一個冒號以及此替換。 – 2009-06-16 19:44:03

0

這可能是你想要什麼:

$expr = "^(ab)|(cd)|(ef)|(gh)|(ij)"; 
while (<IN>) 
{ 
    if (/$expr:/) 
    { 
     s/$expr/$myPattern/; 
     print FILE; 
    } 
} 
0

上面要求做的最簡單的方法是重新使用您的代碼,但包含替換。

while (<IN>) 
{ 
    print FILE if s/^(ab|bc|ef|gh):/MyPattern:/; 
} 

任何左側圖案都將被替換。如果左側不匹配,則不會打印任何內容。

3

一般地,做到這一點,如:

my %subst = ('ab' => 'newab', 'bc' => 'newbc', 'xy' => 'newxy'); 
my $regex = join('|', map quotemeta, sort { length($b) <=> length($a) } keys %subst); 
$regex = qr/^($regex):/; 

while (<IN>) { 
    print FILE if s/$regex/$subst{$1}:/; 
} 

排序把最長的人第一次,因此,如果數據具有AB ::和兩個AB和AB:被取代,AB:被代替AB。

相關問題