2013-04-05 68 views
1

我有一個數組填充了短字符串(@pos)和另一個更大的數組(@exome)。我想從第一個字符串中搜索第二個數組。我們的目標是從打印@exome有符合所有行Perl grep兩個數組

林用perl這是我迄今爲止

#!/usr/bin/perl 
use strict; use warnings; 

my $pos = $ARGV[0]; 
my $exome = $ARGV[1]; 

open (F, "$pos") || die "Could not open $pos: $!\n"; 
my @pos = <F>; 
close F; 

open (F, "$exome") || die "Could not open $exome: $!\n"; 
my @exome = <F>; 
close F; 

foreach (@pos) { 
    my @out = grep(/$_/, @exome); 
    print @out 
} 
+3

什麼是你的問題? – mob 2013-04-05 17:28:55

+0

@JoeFrambach:這不是問題。你的問題是什麼? – Borodin 2013-04-05 18:16:57

回答

1

我想@ikegami已經給出了一個相當不錯的答案,不過,他似乎要獲得在打印的內容陣列錯誤......也許@ user2249959希望@exome陣列打印... 所需的核心代碼不超過兩行:

my $grep_pos = join '|', @pos; 
my @matched_results = grep { /$grep_pos/ } @exome; 

好了,你可以在第二行立即打印出來,但不會有在元素之間的空白陣列。 兩個foreach循環看起來不像Perl,只是我個人認爲...

P.S.我添加了三點要注意
1.小心看不見的「\ n」或「\ r \ n」
2.請注意每個字符串開頭和結尾處的空格。
您可以用簡單的代碼解決了以上兩點,例如:

map { chomp; s/^\s*|\s*$// } @pos; 

這將刪除「\ n」(如果有),並在前面或在年底空格(如果你認爲無意義)。在grep之前做它
3.更重要!注意@pos數組文件中的空白行
如果你的文件是這樣的:

pos_1 
pos_2 
<---- totally blank 
pos_3 

如果你還加入了線加上「|」,它將成爲「POS_1 | POS_2 || pos_3」,這意味着在任何@exome將匹配。 (因爲「||」的)
格格或S ///不會幫助,你有自己跳到這行
只是要小心:)

+0

謝謝。但這似乎不是如果有任何字符後的字符串匹配這就是 如 POS工作: 外顯子組: 1234AB 將不匹配。 AB1234會。有任何想法嗎? – 2013-04-05 20:43:52

+0

@ user2249959,也許我知道發生了什麼事。這是我的猜測:你是否從文件中讀取數組pos和exome?然後1234實際上應該像「1234 \ n」,它的尾部包含一個不可見的字符。因此「1234AB \ n」不匹配,但在頭部添加「AB」(「AB1234 \ n」)仍匹配「1234 \ n」。我也會修改我的代碼,因爲我發現了一個非常令人失望的錯誤。 – noalac 2013-04-06 02:44:03

+0

非常好,謝謝。完美的作品。 – 2013-04-08 17:28:38

2

問題:

  • /$_/意味着$_ =~ /$_/,所以也許你應該爲模式使用不同的變量。
  • 您不會將文本轉換爲正則表達式模式(可以使用quotemeta來完成)
  • 您可能會輸出同一行兩次。
  • 請不要將全局變量用於文件句柄。
  • 不需要將正在搜索的整個文件加載到內存中。

解決方案:

my ($pos_qfn, $exome_qfn) = @ARGV; 

open(my $pos_fh, '<', $pos_qfn) 
    or die("Could not open $pos_qfn: $!\n"); 
my @pos = <$pos_fh>; 
chomp(@pos); 

my $pat = join '|', map quotemeta, @pos; 

open(my $exome_fh, '<', $exome_qfn) 
    or die("Could not open $exome_qfn: $!\n"); 

while (<$exome_fh>) { 
    print if /$pat/; 
} 
+0

@TLP,確實是固定的。 – ikegami 2013-04-05 23:11:30

+0

我認爲你的代碼正在編譯每次調用中的匹配模式。加入後只需添加'$ pat = qr/$ pat /;'就可以解決問題。 – 2013-04-05 23:57:33