使用Perl比较2个文件

时间:2014-02-26 18:09:26

标签: perl oracle11g

目前我需要比较每张表有大约700M +记录的2个表。

我们想出了一个基于文件进行比较的想法,而不是根据我们的数据库性能将其带到数据库。还听说Perl比任何其他编码方法快得多

我们需要将一个文件中的使用计划的移动号码与另一个文件中的相同移动号码进行比较,如果存在且其使用是否匹配,我们只需要在新文件中写入不匹配的记录

示例:

档案1

number, Usage type , Usage Plan , Usage Volume (KB)  ........
12344 , CP         , FB         , 100  ........
12323 , UP         , FB         , 200  ........
12322 , CP         , G+         , 300  ........

文件2

number, Usage type , Usage Plan , Usage Volume (KB)  ........
12344 , CP         , FB         , 100  ........
12323 , UP         , FB         , 210  ........

所以在上面的例子中我的unmatch文件应该包含

不匹配文件

12323 , UP         , FB         , 210  ........
12322 , CP         , G+         , 300  ........

........表示此后有很多列,我们不会用它来比较。他们更像是关于该计划的更多细节。

请分享您对此的建议和编码方法。

我们的目标是在6到7个小时内完成比较..以便装载和其他东西可以在2天内完成..

先谢谢.. 萨姆

2 个答案:

答案 0 :(得分:0)

这是另一种不将整个文件读入内存的方法,由于内存限制可能会出现问题。例如,700M记录x 30字节/ rec = 21GB文件。

它确实要求在从DB导出时按文件对文件进行排序。假设这个数字在增加。

open FILE1, "file1";
open FILE2, "file2";
open OUT, ">out.txt";

$line1 = <FILE1>;
$line2 = <FILE2>;

sub number_part {
    ($line) = @_;
    return $1 if $line =~ /^(\d{1..9})/;
}

while (1) {
    if ($line1 eq $line2) {
        $line1 = <FILE1>;
        $line2 = <FILE2>;

    } elsif ( number_part(line1) == number_part(line2) ) {
        print OUT $line1;
        print OUT $line2;
        $line1 = <FILE1>;
        $line2 = <FILE2>;

    } elsif ( number_part($line1) < number_part($line2) ) {
        print OUT $line1;
        $line1 = <FILE1>;

    } elsif ( number_part(line1) > number_part(line2) ) {
        print OUT $line2;
        $line2 = <FILE2>;
    }

    # Use a dummy record if EOF is reached for either file.
    # Done when EOF is reached for both files.
    $line1 = "9999999999" unless $line1;
    $line2 = "9999999999" unless $line2
    last if $line eq "999999999" and $line2 eq "9999999999";
}

close(FILE1); 
close(FILE2); 
close(OUT);

答案 1 :(得分:-1)

这个怎么样:

use strict;

open FILE1, 'file1.txt';
open FILE2, 'file2.txt';
open OUTPUT, '>output.txt';

my $regex = qr/^ *(\d+) , (.*) , (.*) , (\d+)/;

my $file1;
while(<FILE1>){
  if(/$regex/){
    $file1->{$1}->{type} = $2;
    $file1->{$1}->{plan} = $3;
    $file1->{$1}->{volume} = $4;
  }
}

my $file2;
while(<FILE2>){
  if(/$regex/){
    $file2->{$1}->{type} = $2;
    $file2->{$1}->{plan} = $3;
    $file2->{$1}->{volume} = $4;
  }
}

my $numbers;
$numbers->{$_} = 1 foreach keys %$file1;
$numbers->{$_} = 1 foreach keys %$file2;

my $output;
foreach(keys %$numbers){
  if(defined $file1->{$_} && defined $file2->{$_}){
    if($file1->{$_}->{type} ne $file2->{$_}->{type} || $file1->{$_}->{plan} ne $file2->{$_}->{plan} || $file1->{$_}->{volume} ne $file2->{$_}->{volume}){
      push @$output, [$_, $file2->{$_}->{type}, $file2->{$_}->{plan}, $file2->{$_}->{volume}];
    }
  }elsif(defined $file1->{$_}){
    push @$output, [$_, $file1->{$_}->{type}, $file1->{$_}->{plan}, $file1->{$_}->{volume}];
  }else{
    push @$output, [$_, $file2->{$_}->{type}, $file2->{$_}->{plan}, $file2->{$_}->{volume}];
  }
}

print OUTPUT join(' , ', @$_)."\n" foreach @$output;