2010-03-02 161 views
2

我有包含線看起來像這樣一個文件:的Perl Oneliner解析多個條件中的正則表達式

>AF001546_1 [88 - 462] 1 MGQQ 
>AF001543_1 [88 - 261] ACGT 

這並不是說每行可包含6個OR 5字段。我想要做的是捕獲 字段1,2,3(僅限數量),5(僅限數量)和最後一個字段(ACGT或MGOQ字符串)。

所以預期的輸出是這樣的:

>AF001546_1 88 462 MGQQ 
>AF001543_1 88 261 ACGT 

現在我用Perl的一個班輪是這樣的,但沒有成功

perl -lne 'print "$1 $2 $3 $4" if /(\w+)_\d+\D+(\d+)\D+(\d+)\](\D+)/' 

什麼是做正確的方式?

回答

3
perl -lne 'print "$1 $2 $3 $4" if /(>\w+)\D+(\d+)\D+(\d+)\D+\d*\s+(\w+)/' 
1
while(<>){ 
chomp; 
s/\[|\]//g; 
if ($_ =~ /^>/){ 
    @s = split /\s+/; 
    print "$s[0] $s[1] $s[3]\n"; 
}  
} 

$ perl -F"\s+" -lane '$F[3]=~s/\]//;$F[1]=~s/\[//;print "$F[0] $F[1] $F[3]";' file 
>AF001546_1 88 462 
>AF001543_1 88 261 
1

嘗試這種 perl的-lne '打印 「$ 1 $ 2 $ 3 $ 4」 如果/(\ W +)_ \ d + \ d +(\ d +)\ d +(\ d +)](\ d +)/ M'

你需要使用修改器/平方米

+0

不,編號/ m修飾符只改變^和$,它們甚至不在你的正則表達式中。此外,-n開關意味着它無論如何都會一次處理一條線。 – p00ya

+0

是的,我同意。我想堅持/ m – coder

1

根據空格是很靈活的,這是相當可讀:

print "$1 $2 $3 $4" if /([^_]+)_\d+ \[(\d+) - (\d+)\] (?:\d+)?(.*)/ 
2

您可以使用下面的代碼還

use strict; 
use warnings; 

my $str=">AF001546_1 [88 - 462] 1 MGQQ"; 

if($str=~/(\w+)\s\D([0-9]{2}) - ([0-9]{3})\D\s\d\s(.*)/) 
{ 
    print "$1 $2 $3 $4\n"; 
}