使用两个数组,我需要检查并查看其中一个元素是否出现在另一个数组中,并分别打印匹配的元素

chi*_*und 1 regex string perl

F1.txt

bob
tom
harry
Run Code Online (Sandbox Code Playgroud)

F2.txt

bob
a=1   b=2   c=3
bob
d=4   e=5   f=6
tom
a1=34  b1=32  c1=3443
tom
a2=534  b2=732  c2=673443
Run Code Online (Sandbox Code Playgroud)

结果:

A1.txt

bob
a=1   b=2   c=3
bob
d=4   e=5   f=6
Run Code Online (Sandbox Code Playgroud)

A2.txt

tom
a1=34  b1=32  c1=3443
tom
a2=534  b2=732  c2=673443
Run Code Online (Sandbox Code Playgroud)

我是PERL的新手你可以帮助我解决我的问题.现在我已经提到了两个文件,即F1.txt和F2.txt,我的工作是在F2.txt中搜索F1.txt的任何元素并打印相应的行以及下一行.如果找到一个元素,那么结果必须保存在一个新文件中,我给出了示例A1.txt,它存储了关于bob的所有信息,类似地,A2.txt它存储了关于Tom的所有信息.直到现在我已经尝试过这段代码,但效率不高,

use strict; 
use warnings;  

my $line1; 
my $line2; 
my $fh; 
my $fh1; 
my $counter;  

open  $fh, "<", "F1.txt" or die $!; 
open  $fh1, "<", "F2.txt" or die $!;  

my @b = <$fh>; 
my @a = <$fh1>;  

for (@b) 
{     
  $line1 = $_;     

  for (@a)     
  {         
    $line2 = $_;         
    if ($line1 =~ /^$line2$/)         
    { 
      $counter++;             
      open my $outfile, ">>", "A_${counter}.txt";             
      print $outfile $line2;             
      close $outfile;         
    }
  }
} 
Run Code Online (Sandbox Code Playgroud)

Dav*_* W. 5

无论何时检查重复元素,请考虑哈希.例如,假设您有两个文件:

 File #1      File #2
 Bob          Tom
 Ted          Dick
 Alice        Harry
 Carol        Ted
Run Code Online (Sandbox Code Playgroud)

如果您的工作是在文件#2中找到也在文件#1中的名称,您可以将文件#1中的名称存储在哈希中,然后当您浏览文件#2时,查看是否有任何匹配的名称你的哈希.

首先,让我们在文件#1中阅读:

 use strict;
 use warnings;
 use autodie;  #This way, I don't have to check open statements

 open my $file_1, "<", "file_1";
 my %first_file_name_hash;
 while my $name (<$file_1>) {
    chomp $name;
    $first_file_name_hash{$name} = 1;
 }
 close $file_1;
Run Code Online (Sandbox Code Playgroud)

现在,%first_file_name_hash包含文件#1中的所有名称.

现在让我们打开文件#2,然后通过:

open my $file_2, "<" "file_2";
while my $name (<$file_2>) {
   if ($first_file_name_hash) {
       print "User is in file #1 and file #2\n";
   }
}
close $file_2;
Run Code Online (Sandbox Code Playgroud)

是的,这不是你想要的,但它让你知道如何存储哈希.


哈希具有与值相关联的键.每个条目必须具有唯一键.但是,散列中的每个条目都可能具有重复的值.这是一个简单的哈希:

 $hash{BOB} = "New York";
 $hash{CAROL} = "New York";
 $hash{TED} = "Los Angeles";
 $hash{ALICE} = "Chicago";
Run Code Online (Sandbox Code Playgroud)

在上文中,双方$hash{BOB}$hash{CAROL}具有相同的值(纽约).但是,只能有一个BOBCAROL在哈希中.

哈希的一大优点是通过密钥访问元素非常容易.你知道关键,你可以很容易地提出要素.

在你的情况下,我会使用两个哈希.在第一个哈希中,我将保存$ HASH_1中第一个文件中的所有人的名字.我会在$ HASH_2中保存第二个文件中每个人的名字.不仅如此,我还会将$ HASH_2的值作为文件中的下一行.

这会给你:

$HASH_1{bob} = 1;
$HASH_1{tom} = 1;
$HASH_1{harry} = 1; 

$HASH_2{bob} = a=1  b=2  c=3
               d=4  e=5  f=6
$HASH_2{tom} = a1=34  b1=32  c1=3443
               a2=534   b2=732   c2=673443
Run Code Online (Sandbox Code Playgroud)

注意:散列中的每个条目都有一个单一值的限制,因此当您有两个或多个具有键的行时bob,您必须找到一种处理它们的方法.在这种情况下,如果密钥已经存在$HASH_2,我只需按照NL值附加它.

在现代Perl中,你可以将数组存储在一个哈希中,但你是一个开始的Perl程序员,所以我们将坚持使用更简单的技巧.

这是一个完全未经测试的程序:

use strict;
use warnings;
use autodie;
use feature qw(say);   #Better print that print

# Read in File #1
open my $file_1, "<", "F1.txt";
my %hash_1;
while my $name (<$file_1>) {
   chomp $name;
   $hash_1{$name} = 1;
}
close $file_1;

# Read in File #2 -- a bit trickier

open my $file_2, "<", "F2.txt";
my %hash_2;
while my $name (<$file_2>) {
    chomp $name;
    my $value = <$file_2>;              #The next line
    chomp $value;
    next if not exists $hash_1{$name};  #Not interested if it's not in File #1
    if (exists $hash_2{$name}) {        #We've seen this before!
        $hash_2{$name} = $hash_2{$name} . "\n" . $value; #Appending value
    }
    else {
        $hash_2{$name} = $value;
    }
 }
 close $file_2;
Run Code Online (Sandbox Code Playgroud)

现在,我们以我们想要的方式获得数据.%hash_2包含您需要的一切.我只是不确定你想怎么打印出来.但是,它会是这样的:

 my $counter = 1;    #Used for file numbering..
 foreach my $name (sort keys %hash_2) {
    open my $file, ">", "A" . $counter . "txt";
    say $file "$name";     #Name of person
    my @lines = split /\n/, $hash_2{$key};  #Lines in our hash value
    foreach my $line (@lines) {
      say $file "$line";
    }
    close $file;
    $counter++;
 }
Run Code Online (Sandbox Code Playgroud)

通过使用哈希注意,我避免了双循环,这可能最终耗费大量时间.我只经历了三个循环:前两个读取每个文件.最后一个遍历第二个文件的哈希值,并将其打印出来.

使用哈希是跟踪已阅读数据的好方法.