比较两个文件后如何打印不匹配的数据?

时间:2013-07-17 03:06:04

标签: perl match

我这里有两个文件(文件1和文件2)。我想从两个文件中匹配如下所示的粗体名称。但是我需要以文件1格式打印那些不匹配的数据。我一直在尝试下面的代码,但这不是我想要的结果。如何在匹配后以文件1格式打印那些不匹配的数据?

档案1

ID **alan135/xkr** $work(b05bfn00un0c3)/b05bfn00un0c3 ; #<= b05bfn00un0d0 Size:5848.270996  
ID **John06/ext** $work(b05bfn00ld0p7)/b05bfn00ld0p7 ; #<= b05bfn00ld0s0 Size:INFINITY    
ID **lily099/poli** $work(b05bfn00ld0p7)/b05bfn00ld0p7 ; #<= b05bfn00ld0s0 Size:INFINITY  
ID **sam012/pp** $work(b05bfn00ld0p7)/b05bfn00ld0p7 ; #<= b05bfn00ld0s0 Size:INFINITY  
ID **lily099/poli** $wwrk(b05bfn00ld0p8)/b05bfn00ld0p8 ; #<= b05bfn00ld0s0 Size:INFINITY  
ID **Steve9018** $work(b05bfn00ld0p7)/b05bfn00ld0p7 ; #<= b05bfn00ld0s0 Size:INFINITY 

文件2

Accept => **John06/ext** Max  
Accept => **vivian788/ppr** Maxcap  
Accept => **suzan645/pp** Min  
Accept => **lily099/poli** Max  
Accept => **Nick5670/uu** Max  
Accept => **Anne309/pej** Min  

代码

my ($line1,$line2,@arr1,@arr2,@arr3,@emptyarr);  
@arr1 = <FILE1>;  
@arr2 = <FILE2>;  
foreach $line2 (@arr2) {  
    if ($line2 =~ m/(.*)\s+(.*)\s+(.*)\s+(.*)/) {  
        @arr3 = @emptyarr;    
        my $cname2 = "$2";  
        push (@arr3, $cname2);  
    }  
}   

foreach $line2 (@arr3) {   
    foreach $line1 (@arr1) {  
        if ($line1 =~ m/(.*)\s+(.*)\s+(.*)\s+(.*)\s+(.*)\s+(.*)\s+(.*)\s+(.*)/) {  
            my $cname1 = "$2";  
            if ($cname1 ne $line3) {    
                print NL "$cname1\n";  
            }  
        }  
    }       
}  

预期结果:

ID alan135 / xkr $ work(b05bfn00un0c3)/ b05bfn00un0c3; #&lt; = b05bfn00un0d0大小:5848.270996
   ID sam012 / pp $ work(b05bfn00ld0p7)/ b05bfn00ld0p7; #&lt; = b05bfn00ld0s0尺寸:INFINITY
   ID Steve9018 $ work(b05bfn00ld0p7)/ b05bfn00ld0p7; #&lt; = b05bfn00ld0s0大小:INFINITY

3 个答案:

答案 0 :(得分:1)

这对我有用。您可以用数组替换split('\ n',...)。

use strict;
use warnings;

my $file1 = <<'FILE';
ID **alan135/xkr** $work(b05bfn00un0c3)/b05bfn00un0c3 ; #<= b05bfn00un0d0 Size:5848.270996  
ID **John06/ext** $work(b05bfn00ld0p7)/b05bfn00ld0p7 ; #<= b05bfn00ld0s0 Size:INFINITY    
ID **lily099/poli** $work(b05bfn00ld0p7)/b05bfn00ld0p7 ; #<= b05bfn00ld0s0 Size:INFINITY  
ID **sam012/pp** $work(b05bfn00ld0p7)/b05bfn00ld0p7 ; #<= b05bfn00ld0s0 Size:INFINITY  
ID **lily099/poli** $wwrk(b05bfn00ld0p8)/b05bfn00ld0p8 ; #<= b05bfn00ld0s0 Size:INFINITY  
ID **Steve9018** $work(b05bfn00ld0p7)/b05bfn00ld0p7 ; #<= b05bfn00ld0s0 Size:INFINITY 
FILE

my $file2 = <<'FILE';
Accept => **John06/ext** Max  
Accept => **vivian788/ppr** Maxcap  
Accept => **suzan645/pp** Min  
Accept => **lily099/poli** Max  
Accept => **Nick5670/uu** Max
Accept => **Anne309/pej** Min  
FILE

for (split("\n", $file2)) {

    /.*\*\*(.*)\*\*.*./;
    my $id = $1;
    for (split("\n", $file1)) {

        if ( /${id}/ ) {
            print $_ . "\n";
        }
    }
}

答案 1 :(得分:0)

要在DEBUG模式下运行此脚本,请键入DEBUG=1 script.pl

#!/usr/bin/env perl

use strict;
use warnings;

# --------------------------------------

use charnames qw( :full :short   );
use English   qw( -no_match_vars );  # Avoids regex performance penalty

use Data::Dumper;

# Make Data::Dumper pretty
$Data::Dumper::Sortkeys = 1;
$Data::Dumper::Indent   = 1;

# Set maximum depth for Data::Dumper, zero means unlimited
local $Data::Dumper::Maxdepth = 0;

# conditional compile DEBUGging statements
# See http://lookatperl.blogspot.ca/2013/07/a-look-at-conditional-compiling-of.html
use constant DEBUG => $ENV{DEBUG};

# --------------------------------------

# Put the file names in variables so they can be easily changed.
my $file_name_1 = 'data1.tmp';
my $file_name_2 = 'data2.tmp';

# Read the key names from the second file.
my %key_names = ();
open my $fh2, '<', $file_name_2 or die "could not open $file_name_2: $OS_ERROR\n";
while( my $line = <$fh2> ){
  # names are after 'Accept => '
  if( my ( $name ) = $line =~ m{ \b Accept \s* \=\> \s* (\S+) }msx ){
    $key_names{$name} ++;
  }
}
close $fh2 or die "could not close $file_name_2: $OS_ERROR\n";
print Dumper \%key_names if DEBUG;

# Read the first file and store the _unmatched_ names.
my %lines_of_unmatched = ();
open my $fh1, '<', $file_name_1 or die "could not open $file_name_1: $OS_ERROR\n";
while( my $line = <$fh1> ){
  # name after 'ID'
  if( my ( $name ) = $line =~ m{ \b ID \s+ (\S+) }msx ){
    if( ! exists $key_names{$name} ){
      push @{ $lines_of_unmatched{$name} }, $line;
    }
  }
}
close $fh1 or die "could not close $file_name_1: $OS_ERROR\n";
print Dumper \%lines_of_unmatched if DEBUG;

答案 2 :(得分:0)

use List::Compare;

my @diffs = List::Compare->new(
    [map {/\*\*([^\*]+)\*\*/} <FILE1>], 
    [map {/\*\*([^\*]+)\*\*/} <FILE2>]
)->get_symmetric_difference;

print join("\n", @diffs)."\n";