如何在perl中查找包含两个文件匹配的行?

时间:2015-04-02 01:58:58

标签: perl

我是使用perl的新手。我想要做的是比较两个文件。一个是我的索引文件,我称之为“temp”。我试图用它来搜索我称之为“数组”的主文件。索引文件中只包含数字。我的数组中有些行有这些数字。我一直试图找到这两个文件之间的交集,但我的代码不起作用。这就是我一直想做的事情。

#!/usr/bin/perl
print "Enter the input file:";
my $filename=<STDIN>;
open (FILE, "$filename") || die "Cannot open file: $!";
my @array=<FILE>;
close(FILE);
print "Enter the index file:";
my $temp=<STDIN>;
open (TEMP, "$temp") || die "Cannot open file: $!";
my @temp=<TEMP>;
close(TEMP);
my %seen= ();
foreach (@array) {
    $seen{$_}=1;
 }
 my @intersection=grep($seen{$_}, @temp);
 foreach (@intersection) {
    print "$_\n";
 }

如果我不能使用交集,那么我还能做些什么来移动两个文件之间匹配的每一行?

对于那些要求主文件和索引文件的人:

主文件:

 1  CP  TRT 
 ...
 14  C1  MPE 
 15  C2  MPE 
 ...
 20  CA1 MPE 

索引文件

 20
 24
 22
 17
 18
 ...

我想将包含我的索引文件中的一个数字的行放入一个新数组中。所以只使用这个例子 20 CA1 MPE将被放入一个新阵列。 我的主文件和索引文件都比我显示的要长,但希望能让你知道我正在尝试做什么。

3 个答案:

答案 0 :(得分:0)

我假设是这样的?

use strict;
use warnings;
use Data::Dumper;

# creating arrays instead of reading from file just for demo
# based on the assumption that your files are 1 number per line
# and no need for any particular parsing
my @array = qw/1 2 3 20 60 50 4 5 6 7/; 
my @index = qw/10 12 5 3 2/;
my @intersection = ();
my %hash1 = map{$_ => 1} @array;

foreach (@index)
{
    if (defined $hash1{$_})
    {
        push @intersection, $_;
    }
}


print Dumper(\@intersection);

==== Out ====

$VAR1 = [
      '5',
      '3',
      '2'
    ];

答案 1 :(得分:0)

一些事情:

  • 您的计划中始终有use strict;use warnings;。这将抓住很多可能的错误。
  • 阅读输入后始终chomp。 Perl自动将\n添加到读取行的末尾。 chomp删除了\n
  • 了解更多现代形式的Perl。
  • 使用nemonic变量名称。 $temp并没有削减它。
  • 使用空格来帮助您的代码更具可读性。

你从未说过你得到的错误。我认为它与主文件中的输入与索引文件不匹配这一事实有关。

我使用哈希创建索引文件可以通过my ($index) = split /\s+/, $line;使用的索引:

#! /usr/bin/env perl
#
use strict;
use warnings;
use autodie;
use feature qw(say);


print "Input file name: ";
my $input_file = <STDIN>;
chomp $input_file;             # Chomp Input!

print "Index file name: ";
my $index_file = <STDIN>;
chomp $index_file;             # Chomp Input!

open my $input_fh, "<", $input_file;

my %hash;
while ( my $line = <$input_fh> ) {
    chomp $line;
    #
    # Using split to find the item to index on
    #
    my ($index) = split /\s+/, $line;
    $hash{$index} = $line;
}
close $input_fh;

open my $index_fh, "<", $index_file;

while ( my $index = <$index_fh> ) {
    chomp $index;
    #
    # Now index can look up lines
    #
    if( exists $hash{$index} ) {
        say qq(Index: $index  Line: "$hash{$index}");
    }
    else {
        say qq(Index "$index" doesn't exist in file.);
    }
}

答案 2 :(得分:0)

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

@ARGV = 'main_file';

open(my $fh_idx, '<', 'index_file');
chomp(my @idx = <$fh_idx>);
close($fh_idx);

while (defined(my $r = <>)) {
    print $r if grep { $r =~ /^[ \t]*$_/ } @idx;
}

您可能希望替换<STDIN>

的硬编码文件名

仅供参考:暂时情况下的defined来电可能是“optional”。