比较两个文件以查找常见和唯一条目

时间:2018-07-09 15:08:53

标签: arrays perl hash

我想比较两个文件中的条目。

第一个文件

ch1 12345 ch1 12900 Del
ch1 13000 ch1 13689 Del
ch2 14567 ch2 14905 Del
ch4 23001 ch4 26019 Del

第二个文件

ch1 12309 ch1 12865 
ch2 14531 ch2 14871 
ch3 16909 ch3 16990
ch4 45401 ch4 45810
  • 第一个文件和第二个文件都通用的条目(通用条目的标准在两侧至少具有50个位置)

    ch1 12345 ch1 12900 Del, ch1 12309 ch1 12865
    ch2 14567 ch2 14905 Del, ch2 14531 ch2 14871 
    
  • 第一个文件唯一的条目

    ch1 13000 ch1 13689 Del
    ch4 23001 ch4 26019 Del
    
  • 第二个文件唯一的条目

    ch3 16909 ch3 1699
    ch4 45401 ch4 45810
    

我编写了一个Perl程序,将一个数组循环到另一个数组中,并标识了公共条目,但是使用这种方法,我无法标识唯一条目。

1 个答案:

答案 0 :(得分:-1)

您可以尝试以下程序。

如果您改变主意必须发生多少次 在两侧,更改$limit变量的值。 也许只要1就足够了?

use strict; use warnings;
# Count text occurrences in 2 files

my %counts;         # Hash of arrays (occurrence counters)

sub inputProcess {
  # Process input file
  my $fn = shift;   # File name
  my $n = shift;    # Counter index
  open (my $fh, '<', $fn) or die "Can't open $fn: $!";
  while (<$fh>) {
    chomp;
    $counts{$_}[$n]++;
  }
}

sub readCounts {
  # Read counters, substituting 0 if any does not exist
  my $cnt = shift;  # Reference to array of counters
  my @v = (0, 0);
  foreach my $i ( 0 .. $#v ) {
    $v[$i] = $cnt->[$i] if exists $cnt->[$i];
  }
  return @v;
}

sub printUniq {
  # Print unique entries for the given counter
  my $myCnt = shift;            # "My" counter
  my $otherCnt = 1 - $myCnt;    # The "other" counter
  print "Unique entries from file $myCnt:\n";
  foreach my $key (sort keys %counts) {
    my $val = $counts{$key};
    my @v = readCounts($val);
    if ($v[$myCnt] > 0 && $v[$otherCnt] == 0) {
      printf "%s\n", $key;
    }
  }
}

sub printCommon {
  # Print common entries for both files
  print "Common entries for both files:\n";
  my $limit = 50;
  foreach my $key (sort keys %counts) {
    my $val = $counts{$key};
    my @v = readCounts($val);
    if ($v[0] >= $limit && $v[1] >= $limit) {
      printf "%s\n", $key;
    }
  }
}

inputProcess('Inp1.txt', 0);
inputProcess('Inp2.txt', 1);
print "All entries and counts\n";
foreach my $key (sort keys %counts) {
  my $val = $counts{$key};
  my ($v0, $v1) = readCounts($val);
  printf "%-16s / %3d, %3d\n", $key, $v0, $v1;
}
printUniq(0);
printUniq(1);
printCommon();

这个想法是使用(引用)数组的哈希。 密钥只是从文件中读取的条目。 每个文件的两个数组(哈希中的值)都包含2个计数器。

程序会打印排序的条目,但是如果您愿意,只需删除 排序。

编写上述程序时,我假设每行是一个单独的条目。如果不是这种情况,请相应地修改 inputProcess 函数。

还有另一句话:第一个文件在每一行的末尾包含 Del , 而第二个文件则没有。这样的条目(全行)将不会“匹配”。