代码之家  ›  专栏  ›  技术社区  ›  Ivan

如何在Perl中正确地找到两个文件中的双条目?

  •  1
  • Ivan  · 技术社区  · 7 年前

    假设我有两个包含ip地址列表的文件。第一个文件中的行是唯一的。第二行可能与第一行相同,也可能不同。

    我需要的是比较两个文件,并从第二个文件中删除可能的双文件,以便稍后将其与基文件合并。

    我已经成功地编写了以下代码,它似乎工作正常,但我有一种坚定的感觉,这段代码可以改进,或者我可能完全遗漏了一些重要的概念。

    是否有任何方法可以在不使用复杂数据结构(即hashrefs)的情况下解决该任务?

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    my $base = shift @ARGV;
    my $input = shift @ARGV;
    my $res = 'result.txt';
    
    open ("BASE","<","$base");
    open ("INP","<","$input");
    open ("RES", ">", "$res");
    
    my $rhash = {}; # result hash
    
    while (my $line = <BASE>) {chomp($line); $rhash->{$line}{'res'} = 1;} # create uniq table
    while (my $line = <INP>) { chomp($line); $rhash->{$line}{'res'}++; $rhash->{$line}{'new'} = 1; } # create compare table marking it's entries as new and incrementing double keys 
    close BASE;
    close INP;
    
    for my $line (sort keys %$rhash) {
        next if $line =~ /\#/; # removing comments
        printf("%-30s%3s%1s", $line, $rhash->{$line}{'res'}, "\n") if $rhash->{$line}{'res'} > 1; # kinda diagnosti output of doubles
        if (($rhash->{$line}{'new'}) and ($rhash->{$line}{'res'} < 2)) {
            print RES "$line\n"; # printing new uniq entries to result file
        }
    }
    close RES;
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Chris Charley    7 年前

    如果我正确理解file1和file2都包含IP(每个文件中都是唯一的),并且您希望在file2中获得IP,而不是在file1中。如果是这样,那么下面的代码可能达到了您的目标。

    虽然您的代码似乎可以做到这一点,但这可能更清楚。

    #!/usr/bin/perl
    use strict;
    use warnings;
    
    my $base = shift @ARGV;
    my $input = shift @ARGV;
    my $res = 'result.txt';
    
    open ("BASE","<","$base") or die $!;
    open ("INP","<","$input") or die $!;
    open ("RES", ">", "$res") or die $!;
    
    my %seen;
    
    while (my $line = <BASE>) {
        chomp $line;
        $seen{$line}++;
    }
    close BASE or die $!;
    
    while (my $line = <INP>) {
        chomp $line;
        print RES "$line\n" unless $seen{$line}; # only in file2 not in file1
    }
    close INP or die $!;
    close RES or die $!;