2012-04-30 60 views
0

之间我有两个文件:file1.txtfile2.txt。无论包含此格式的行:使用Perl来搜索匹配两个文件

文件1

name1:value1 

文件2

name2:value2 

我要检查,如果value1list2发现(在name2字符串)

我有这个功能:

#!/usr/bin/perl 
use warnings; 
use Parallel::ForkManager; 

sub loadf($); 

print "Starting main program\n"; 
my @list1 = loadf("list1.txt"); 
my @list2 = loadf("list2.txt"); 

my $workernum = 10; 
open(OK, '>>', 'valid.txt'); 
open(ER, '>>', 'invalid.txt'); 
$pm = new Parallel::ForkManager($workernum); 

my $cnt = 0; 
foreach $line (@list1) { 
    $cnt++; 
    my $pid = $pm->start and next; 
    my @data1 = split(":", $line); 
    my $name1 = $data1[0]; 
    my $value1 = $data1[1]; 
    my @data2 = split(":", $list2); 
    my $name2 = $data2[0]; 
    my $value2 = $data2[1]; 

    if (/$value1/i ~~ @list2) 
    { 
     print OK $name1 . " - " . $value2 . "\n"; 
     print " [+] Found: " . $name1 . " - " . $value2 . "\n"; 
    } 
    else 
    { 
     print ER $name1 . "\n"; 
     print " [x] Unknown: " . $name1 . " - " . $value1 . "\n"; 
    } 
    $pm->finish; 
} 

close(OK); 
close(ER); 
print "\n*** Finished ***\n"; 

sub loadf($) { 
    my @file; 
    open(FILE, $_[0] . "\n") or die("[+] Couldn't open " . $_[0] . "\n"); 
    @file = <FILE>; 
    close(FILE); 
    return @file; 
} 

__END__ 

这是行不通的。我究竟做错了什么 ?

+0

为什么要用叉子你这个? – askovpen

+0

我想用多线程来处理它,尝试过并没有工作,所以平行的叉子赢得了它的工作。但这并不重要...... –

+0

尝试从'sub loadf'的'open'中删除''\ n“'。当我尝试打开名称中包含换行符的文件时,它不起作用。 – simbabque

回答

1
#!/usr/bin/perl 

open(F,'list1.txt'); 
my @list1=<F>; 
close(F); 
open(F,'list2.txt'); 
my @list2=<F>; 
close(F); 
chomp(@list1,@list2); 
foreach my $line (@list1) 
{ 
    if ($line=~/.+\:.+/) 
    { 
     my @data1 = split(":", $line); 
     if (my @d2=grep /$data1[1]\:/i,@list2){print " [+] Found: " . $data1[0] . " - " . [split(':',$d2[0])]->[1] . "\n"; } 
     else { print " [x] Unknown: " . $data1[0] . " - " . $data1[1] . "\n"; } 
    } 
} 
+0

使用未初始化值或字符串在test.pl第21行,这是行:if(grep的/ \:$数据1 [1]/@列表2) {print“[+] Found:”。 $ data1 [0]。 “ - ”。 $ data1 [1]。“\ n” 个; } –

+0

和我需要的格式如果找到是:name1:value2。我的意思是如果在value1中找到name2来打印以屏幕/文件以下行:name1:value2 –

+0

@SamReina修复 – askovpen

0

呃......我真的不明白你的算法,对不起。首先,将比较文件中的所有行读入两个数组,然后分叉处理器循环,但正如我所看到的那样,不会尝试将这些工作者的作业分成几块(以便与之并行)。

我建议尝试有点不同的方法:啜只有第二个文件,然后处理由行的第一个文件中的行。你没有提到第二个文件的名称和值是否是唯一的;我想他们不是,但如果他们是这样的话,程序可以变得更简单。

open my $caf, '<', 'list2.txt' or die $!, "\n"; 
my $checkedAgainst = do { local $/; <$caf>; }; 

open my $cf, '<', 'list1.txt' or die $!, "\n"; 

my $workernum = 10; 
$pm = new Parallel::ForkManager($workernum); 

while (<$cf>) { 
    my $pid = $pm->start and next; 
    my ($nameToCheck, $valueToCheck) = split /:/; 
    if ($checkedAgainst =~ /^\Q$valueToCheck\E:(.+)$/m) { 
    print " [+] Found: $nameToCheck - $1", "\n"; 
    } 
    else { 
    print " [x] Unknown: $nameToCheck - $valueToCheck", "\n"; 
    } 
} 
$pm->finish; 

换句话说,我首先加载第二文件到一个大的字符串,然后尝试与来自第一文件(逐行)的线相匹配。我不知道,你的价值观中可能出现什么符号,这就是为什么\ Q- \ E(quotemeta操作符)在那里使用的原因。

更新:试图使这个代码分叉,没有办法测试它,虽然我站在哪里。

+0

name1,name2和value2是唯一的。只有来自第一个文件的value1不是唯一的。我想用叉子,因为我想更快地处理文件。 file1大约20Mb,file2大约有1000条记录 –

+0

,你的答案可能非常好,但我不知道如何根据你的答案修改我的脚本,我的意思是在我的fork函数中添加一段代码,因为我不'不了解它。对我来说太先进 –

+0

我很抱歉,但为什么你打算首先在这里使用叉子? – raina77ow