使用Perl比较2个文件
目前,我需要比较两个表,每个表有大约700M+的记录 我们提出了一个想法,根据我们的数据库性能,在基于文件的数据库中进行比较,而不是将其带到数据库中。还听说Perl比任何其他编码方法都快得多 我们需要将一个文件中的手机号码使用计划与另一个文件中的相同手机号码进行比较,如果存在并且其使用情况是否匹配,我们需要在新文件中只写入不匹配的记录 例如: 文件1使用Perl比较2个文件,perl,oracle11g,Perl,Oracle11g,目前,我需要比较两个表,每个表有大约700M+的记录 我们提出了一个想法,根据我们的数据库性能,在基于文件的数据库中进行比较,而不是将其带到数据库中。还听说Perl比任何其他编码方法都快得多 我们需要将一个文件中的手机号码使用计划与另一个文件中的相同手机号码进行比较,如果存在并且其使用情况是否匹配,我们需要在新文件中只写入不匹配的记录 例如: 文件1 number, Usage type , Usage Plan , Usage Volume (KB) ........ 12344 , CP
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 ........
因此,在上述情况下,我的不匹配文件应该包含
不匹配文件
12323 , UP , FB , 210 ........
12322 , CP , G+ , 300 ........
….
表示在此之后有许多列,我们将不使用这些列进行比较。他们更喜欢这个计划的细节
请在此分享您的建议和编码想法
我们的目标是在6-7小时内完成比较。。以便在2天内完成装载和其他工作
提前谢谢。。
山姆这个怎么样:
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;
使用严格;
打开FILE1,'FILE1.txt';
打开文件2,‘FILE2.txt’;
打开输出“>OUTPUT.txt”;
我的$regex=qr/^*(\d+)、(.*)、(.*)、(\d+)/;
我的$file1;
while(){
如果(/$regex/){
$file1->{$1}->{type}=$2;
$file1->{$1}->{plan}=$3;
$file1->{$1}->{volume}=$4;
}
}
我的$file2;
while(){
如果(/$regex/){
$file2->{$1}->{type}=$2;
$file2->{$1}->{plan}=$3;
$file2->{$1}->{volume}=$4;
}
}
我的美元号码;
$numbers->{${}=1 foreach key%$file1;
$numbers->{${}=1 foreach key%$file2;
我的美元产出;
foreach(键%$number){
if(定义的$file1->{$\u}&&defined的$file2->{$\u}){
如果($file1->{$}->{type}ne$file2->{$}->{type}}}{124;$$file1->{$}->{plan}ne$file2->{$$}->{plan}}{124;$$file1->{${$}->{volume}ne$file2->{volume}){
push@$output,[$\$file2->{$\}->{type},$file2->{$\}->{plan},$file2->{$\}->{volume}];
}
}elsif(定义为$file1->{$}){
push@$output,[$\$file1->{$\}->{type},$file1->{$\}->{plan},$file1->{$\}->{volume}];
}否则{
push@$output,[$\$file2->{$\}->{type},$file2->{$\}->{plan},$file2->{$\}->{volume}];
}
}
打印输出联接(',',@$)。“\n”foreach@$输出;
这里是另一种不将整个文件读入内存的方法,这可能是由于内存限制造成的问题。例如,700M记录x30字节/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”;
打开文件2,“文件2”;
打开“>OUT.txt”;
$line1=;
$line2=;
子编号\u零件{
($line)=@;
如果$line=~/^(\d{1..9})/,则返回$1;
}
而(1){
如果($line1 eq$line2){
$line1=;
$line2=;
}elsif(编号零件(第1行)=编号零件(第2行)){
打印$line1;
打印$line2;
$line1=;
$line2=;
}elsif(数字部分($line1)<数字部分($line2)){
打印$line1;
$line1=;
}elsif(编号零件(第1行)>编号零件(第2行)){
打印$line2;
$line2=;
}
#如果任一文件达到EOF,则使用虚拟记录。
#当两个文件都达到EOF时完成。
$line1=“999999999”除非$line1;
$line2=“9999999999”除非$line2
如果$line eq“9999999”和$line2 eq“9999999999”,则为最后一个;
}
关闭(文件1);
关闭(文件2);
收尾;
您尝试过什么?另外,文件1中的每一行是否保证存在于文件2中?每个文件中的记录的顺序是否相同?不能保证它会存在,也不能保证它们不会按顺序排序。您似乎忘记了指定遇到的问题。我会使用“无法比较”的方法。它的数据比较模式将根据您的规范的一个关键字段(或多个字段)匹配记录。我介绍的解决方案适用于静态文件和不断修改的文件。如果您在特定时间执行代码,您将获得该特定时间的输出。当文件更改时,应再次执行以获得新的输出。您可以使用Linux下的“cron”或Windows下的“预定任务”(和朋友)来自动执行此操作