比较文件行以匹配第二个文件中的任何位置

时间:2013-05-24 19:07:02

标签: perl file compare

这令人沮丧。 我有2个文本文件,每行只是一个电话号码。 我需要从file1读取第一行,并搜索file2以获得匹配。 如果不匹配,请将行值写入输出文件。 我一直在尝试这个,但我知道它错了。

$file1 = 'pokus1.txt';
$file2 = 'pokus2.txt';

open (F1, $file1) || die ("Could not open $file1!");
open (F2, $file2) || die ("Could not open $file2!");
open (OUTFILE, '>>output\output_x1.txt');
@f1data = <F1>;
@f2data = <F2>;

while (@f1data){
    @grp = grep {/$f1data/} @f2data;

    print OUTFILE "$grp";
}
close (F1);
close (F2);
close (OUTFILE);

我希望有人能帮忙吗? 谢谢 布伦特

3 个答案:

答案 0 :(得分:2)

bash:

不存在

grep -vf file1 file2&gt; file3的

共享

grep -f file1 file2&gt; file4将

答案 1 :(得分:1)

一种常规解决方案,您处理一个文件,将其数据保存为哈希的键,然后处理另一个文件,查看该密钥是否存在:

#!/usr/bin/env perl

use warnings;
use strict;

my (%phone);

open my $fh1, '<', shift or die;
open my $fh2, '<', shift or die;
##open my $ofh, '>>', shift or die;

while ( <$fh2> ) { 
    chomp;
    $phone{ $_ } = 1;
}

while ( <$fh1> ) { 
    chomp;
    next if exists $phone{ $_ };
    ##printf $ofh qq|%s\n|, $_;
    printf qq|%s\n|, $_;
}

exit 0;

像以下一样运行:

perl script.pl file1 file2 > outfile

答案 2 :(得分:1)

每当你得到一个是另一个组类型问题的一个组中的一个数据时(并且它们会出现相当多,你应该考虑哈希值。

哈希是一种键控查找。假设您创建了一个关键字,请说...我不知道...从文件#1中取出的电话号码。如果您在文件#2中读取一行,只需查看哈希就可以轻松查看它是否在文件#1中。快速,高效。

use strict;   #ALWAYS ALWAYS ALWAYS
use warnings; #ALWAYS ALWAYS ALWAYS

use autodie;  #Will end the program if files you try to open don't exist

# Constants are a great way of storing data that is ...uh... constant
use constant {
    FILE_1    =>  "a1.txt",
    FILE_2    =>  "a2.txt",
};

my %phone_hash;

open my $phone_num1_fh, "<", FILE_1;

#Let's build our phone number hash
while ( my $phone_num = <$phone_num1_fh> ) {
    chomp $phone_num;
    $phone_hash{ $phone_num } = 1;   #Doesn't really matter, but best not a zero value
}
close $phone_num1_fh;

#Now that we have our phone hash, let's see if it's in file #2
open my $phone_num2_fh, "<", FILE_2;
while ( my $phone_num = <$phone_num2_fh> ) {
    chomp $phone_num;
    if ( exists $phone_hash { $phone_num } ) {
        print "$phone_num is in file #1 and file #2";
    }
    else {
        print "$phone_num is only in file #2";
    }
}

看看它有多好用。唯一的问题是文件#1中可能存在不在文件#2中的电话号码。您可以通过为文件#2中的所有电话号码创建第二个哈希来解决此问题。

让我们再用两个哈希来做这件事:

my %phone_hash1;
my %phone_hash2;

open my $phone_num1_fh, "<", FILE_1;

while ( my $phone_num = <$phone_num1_fh> ) {
    chomp $phone_num;
    $phone_hash1{ $phone_num } = 1;
}
close $phone_num1_fh;

open my $phone_num2_fh, "<", FILE_2;

while ( my $phone_num = <$phone_num2_fh> ) {
    chomp $phone_num;
    $phone_hash2{ $phone_num } = 1;
}
close $phone_num1_fh;

现在,我们将使用keys列出密钥并通过它们。当手机处于两个哈希值时,我将创建一个%in_common哈希

my %in_common;

for my $phone ( keys %phone_hash1 ) {
    if ( $phone_hash2{$phone} ) { 
       $in_common{$phone} = 1;    #Phone numbers in common between the two lists
    }
}

现在,我有三个哈希%phone_hash1%phone_hash2%in_common

for my $phone ( sort keys %phone_hash1 ) {
    if ( not $in_common{$phone} ) {
         print "Phone number $phone is only in the first file\n";
    }
}

for my $phone ( sort keys %phone_hash2 ) {
    if ( not $in_common{$phone} ) {
        print "Phone number $phone is only in " . FILE_2 . "\n";
    }
}

for my $phone ( sort keys %in_common ) {
    print "Phone number $phone is in both files\n";
}

请注意,在此示例中,我没有使用exists来查看哈希中是否存在密钥。也就是说,我只是将if ( $phone_hash2{$phone} )代替if ( exists $phone_hash2{$phone} )。第一种形式检查是否定义了键 - 即使该值是空字符串或数字为零。

只要值不为零,空字符串或未定义,第二种形式就为真。由于我故意将哈希值设置为1,因此我可以使用此表单。使用exists是一个好习惯,因为有一种情况是有效值可能是空字符串或零。但是,有些人喜欢代码读取的方式,而不使用exists