2013-11-26 62 views
0

我正在寫perl腳本,基本上要打開一個文件有很多字符串(一行中有一個字符串),並比較每個字符串是否存在在另一個文件(搜索文件)和打印的它每次出現,我已經寫了下面的代碼爲一個特定的字符串找到。我怎樣才能提高它從一個文件中的字符串列表。在一個文件中搜索一組字符串是否存在於另一個文件中

open(DATA, "<filetosearch.txt") or die "Couldn't open file filetosearch.txt for reading: $!"; 
my $find = "word or string to find"; 
#open FILE, "<signatures.txt"; 
my @lines = <DATA>; 
print "Lined that matched $find\n"; 
for (@lines) { 
    if ($_ =~ /$find/) { 
     print "$_\n"; 
    } 
} 
+0

將從兩個文件存放在內存中的字符串一下子? – woolstar

+0

你正在打開filetosearch.txt來寫作,而不是閱讀。 – woolstar

+0

是的,這些文件大約500行,適合內存。好吧,我將更正filetosearch.txt只讀爲:打開(DATA,「 Sharath

回答

0

好,像這將會更快。

sub testmatch 
{ 
    my ($find, $linesref)= @_ ; 

    for (@$linesref) { if ($_ =~ /$find/) { return 1 ; } } 
    return 0 ; 
} 

{ 
    open(DATA, "<filetosearch.txt") or die "die" ; 
    my @lines = <DATA> ; 

    open(SRC, "tests.txt") ; 
    while (<SRC>) 
    { 
    if (testmatch($_, \@lines)) { print "a match\n" } 
    } 
} 

如果它的匹配全行到全行,yo ü可以包裝一條線作爲鍵的哈希,只是測試所有腦幹:

{ 
    open(DATA, "<filetosearch.txt") or die "die" ; 
    my %lines ; 
    @lines{<DATA>}= undef ; 

    open(SRC, "tests.txt") ; 
    while (<SRC>) 
    { 
    if ($_ ~~ %lines) { print "a match\n" } 
    } 
} 
+1

永遠不會失敗'use strict;使用警告;'。 – Kenosis

+0

其實我只是用5。012; – woolstar

+0

非常感謝Woolstar。但我忘了包括我想從比賽模式之前打印3行。我怎麼做? – Sharath

0

這裏的另一種選擇:

use strict; 
use warnings; 

my $searchFile = pop; 
my @strings = map { chomp; "\Q$_\E" } <>; 
my $regex  = '(?:' . (join '|', @strings) . ')'; 

push @ARGV, $searchFile; 

while (<>) { 
    print if /$regex/; 
} 

用法:perl script.pl strings.txt searchFile.txt [>outFile.txt]

最後,可選參數指示輸出一份文件。

首先,搜索文件的名稱是(隱式)pop預約@ARGV並保存以備後用。然後讀取字符串文件(<>)和map用於chomp每行,轉義元字符(\Q\E,如果可能有正則表達式字符,例如'。'或'*'等,在字符串中),那麼這些行被傳遞給一個數組。使用正則表達式替換字符(|)對數組元素進行join編輯,以有效地形成將與每個搜索文件的行匹配的所有字符串的OR語句。接下來,搜索文件的名稱是push ed @ARGV所以它的行可以被搜索。如果在線上找到其中一個字符串,則每行都是chomp ed和print

希望這會有所幫助!

1

我想嘗試這樣的事:

use strict; 
use warnings; 
use Tie::File; 

tie my @lines, 'Tie::File', 'filetosearch.txt'; 
my @matched; 
my @result; 
tie my @patterns, 'Tie::File', 'patterns.txt'; 
foreach my $pattern (@patterns) 
{ 
    $pattern = quotemeta $pattern; 
    @matched = grep { /$pattern/ } @lines; 
    push @result, @matched; 
} 
  • 我使用領帶::文件,因爲它很方便(尤其是沒有在這種情況下,但其他人),其他(也許很多人的?)會不同意,但它並不重要這裏
  • 的grep的一個核心功能,那就是它做什麼很不錯(在我的經驗)
+1

+1,用於爲這種情況建議使用Tie :: File。它可以*大大慢速*大文件,但OP不處理這種情況。考慮'/ \ Q $ pattern \ E /',因爲字符串中可能有元字符。 – Kenosis

+0

@Kenosis謝謝Kenosis,我插入了你的建議。我個人更喜歡使用quotemeta,因爲我認爲它提高了可讀性。 –

+0

非常歡迎!您的可讀性點是有道理的。在'grep'ping之前,你當然可以'$ pattern = quotemeta $ pattern;'' – Kenosis

0

也許這樣的事情會做的工作:

open FILE1, "filetosearch.txt"; 
my @arrFileToSearch = <FILE1>; 
close FILE1; 

open FILE2, "signatures.txt"; 
my @arrSignatures = <FILE2>; 
close FILE2; 

for(my $i = 0; defined($arrFileToSearch[$i]);$i++){ 
    foreach my $signature(@arrSignatures){ 
     chomp($signature); 
     $signature = quotemeta($signature);#to be sure you are escaping special characters 
     if($arrFileToSearch[$i] =~ /$signature/){ 
      print $arrFileToSearch[$i-3];#or any other index that you want 
     } 
    } 

}

相關問題