比较两个文件,编写更新/删除/插入输出文件

时间:2013-01-31 08:54:21

标签: perl csv

我正在编写一个脚本,用于检查基于2个文件所做的更改。这些文件共享一个公共ID,如果匹配,则必须比较5个元素(包括基本信息,地址,邮政编码等)。如果一个或多个元素不匹配,它应该从第一个文件末尾的第二个文件中推送更改(所以之后我可以轻松查看所做的更改)

第一个文件是基础,另一个文件来自一个月后,包含三种方式的更改:我已经覆盖了第一个文件。如果ID不匹配,则应将其写入新文件。这可以通过两种方式实现:新文件中的id不再存在(因此它可能已被删除),这将是第二个输出文件,第三个文件是旧文件中的id不存在的位置(意味着它是新的。)

我一直专注于第一部分,即元素的比较。比较元素并不难,但我似乎无法弄清楚如何正确地将第二个文件中的元素添加到现有数组的末尾。当我使用push变量时它不会在最后添加但显示在下一行,所以我认为在它们之间有一条新线但是我用chomp删除了它。那为什么会这样呢?

第二个问题:如何轻松完成第二部分,检查新/旧ID并写入自己的文件。

这是我现在的距离(不远)。这只是比较部分,仍在使用如何合并写入包含旧(已删除)/新条目的其他2个文件。我是怎么想的:

为:

 1204;Hotel New York;Street 4;AABBCC;New York;12345679;www.hotelnewyork.com;52.3662946;3.876277;5365;3
 783;Hotel Amsterdam;Damstraat 10;1234 AB;Amsterdam;234567890;www.hotelamsterdam.com;52.171902;4.28061;5367;4
 ;Hotel Atsterdem
 ;Damstraat 20
 1692;Hotel Berlin;Strasse 4;123456;Berlin;4567890;www.hotelberlin.com;43.218571;6.862009;5368;3
 2300;Hotel Barcelona;Avenue 3;AAA 123;Barcelona;3566677;;54.171902;6.102174;5371;4
 ;Hotel Barca                                   

好:

1204;Hotel New York;Street 4;AABBCC;New York;12345679;www.hotelnewyork.com;52.3662946;3.876277;5365;3
783;Hotel Amsterdam;Damstraat 10;1234 AB;Amsterdam;234567890;www.hotelamsterdam.com;52.171902;4.28061;5367;4;Hotel Atsterdem;Damstraat 20
1692;Hotel Berlin;Strasse 4;123456;Berlin;4567890;www.hotelberlin.com;43.218571;6.862009;5368;3
2300;Hotel Barcelona;Avenue 3;AAA 123;Barcelona;3566677;;54.171902;6.102174;5371;4;Hotel Barca

这是我一直在使用的剧本,我知道这可能不是达到目标最复杂的方式,但我担心我不能做得更好。

 #!/usr/bin/perl
 use strict;
 use warnings; 

 if ($#ARGV != 4){
print "4 namen opgeven\n";
exit;
} 

 my $inputfile1=$ARGV[0];
 my $inputfile2=$ARGV[1];
 my $outputfile1=$ARGV[2];
 my $outputfile2=$ARGV[3];
 my $outputfile3=$ARGV[4];

 open(INFILE1,$inputfile1) || die "Not found :$!\n";
 open(INFILE2,$inputfile2) || die "Not found :$!\n";
 open(OUTFILE_1,">$outputfile1") || die "In use :$!\n";
 open(OUTFILE_2,">$outputfile2") || die "In use :$!\n";
 open(OUTFILE_3,">$outputfile3") || die "In use :$!\n";

 my $i = 0;
 my $j = 0;
 my $newline = 0;

 my @infile1=<INFILE1>;
 my @infile2=<INFILE2>;

 foreach ( @infile1 ){
    s/"//g;
    my @elements = split(";",$infile1[$i]);
    chomp(@elements);
    $j = 0;

    foreach ( @infile2 ){
        s/"//g;
        my @loopelements = split(";",$infile2[$j]);
        #chomp(@loopelements);
        $newline = 0;

        if ($elements[10] == $loopelements[10]){

            $newline = 1;

            if ($elements[1] ne $loopelements[1]){
                push(@elements, $loopelements[1]."\n");
                }
            if ($elements[2] ne $loopelements[2]){
                push(@elements, $loopelements[2]."\n");
                }                   
            if ($elements[3] ne $loopelements[3]){
                push(@elements, $loopelements[3]."\n");             
                }                   
            if ($elements[4] ne $loopelements[4]){
                push(@elements, $loopelements[4]."\n"); 
                }                   
            if ($elements[5] ne $loopelements[5]){
                push(@elements, $loopelements[5]."\n");
                }   
            if ($elements[6] ne $loopelements[6]){
                push(@elements, $loopelements[6]."\n");
                }               
            } 

        $j = $j+1;
        }

if ($newline == 0){
    $elements[11] = $elements[11]."\n";
    }       

@elements = join(";",@elements);    
print OUTFILE_1 "@elements";
$i = $i+1;
}

 close(INFILE1);
 close(INFILE2);
 close(OUTFILE_1);
 close(OUTFILE_2);
 close(OUTFILE_3);  

1 个答案:

答案 0 :(得分:0)

听起来你正在做的事情可以通过数据库轻松处理。我会考虑改变你的设计。从长远来看,它会让你的生活更轻松。

安装类似MySQL的东西并不太难。但是,您甚至不必这样做就可以使用Perl数据库。有几个完全独立的解决方案可以为您提供Perl中的数据库。例如,请查看DBD::SQLite。您需要做的就是安装一个Perl模块,并拥有一个完整的数据库。

也许你出于某种原因(例如你的老板......)仍然坚持使用这种格式。但即使你必须以这种格式保存文件,你也可以仍然使用它们,就好像它们是一个数据库一样。 DBD::CSV正是这样做的!