搜索文件中的一组字符串是否存在于另一个文件中

时间:2013-11-26 04:34:21

标签: perl

我正在写入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";
    }
}

4 个答案:

答案 0 :(得分: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;
}
  • 我使用Tie :: File,因为它很方便(特别是在这种情况下,而不是其他人),其他人(也许还有很多人?)会不同意,但这里并不重要
  • grep是一个核心功能,它非常擅长(根据我的经验)

答案 1 :(得分: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" }
  }
}

如果匹配整行到实线,您可以将一行打包为哈希的密钥,只测试存在:

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

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

答案 2 :(得分: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 ped off @ARGV并保存以供日后使用。然后读取字符串的文件(<>),map用于chomp每一行,转义元字符(\Q\E,例如,字符串中可能存在正则表达式字符,例如“。”或“*”等,然后将这些行传递给数组。数组的元素join与正则表达式交替字符(|)一起使用,以有效地形成将与每个搜索文件的行匹配的所有字符串的OR语句。接下来,搜索文件的名称push被编辑到@ARGV,因此可以搜索其行。同样,如果在该行上找到其中一个字符串,则每行都为chompprint

希望这有帮助!

答案 3 :(得分: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
        }
    }

}