# pass in _references_ to the arrays of lists @L and @R # each element is the list of fields on a given line COMPARE(\@L,\@R); sub COMPARE { # $L is a reference to @L, $R is a reference to @R my( $L, $R ) = @_; # @Ret isn't used, it's just here to confuse you :) my @Ret = (); # %L is a hash with an entry for every index in @L # so we can skip lines already matched, and print # unmatched lines at the end my %L = map { $_ => $_; } 0..$#$L; # %R is a hash with an entry for every index in @R my %R = map { $_ => $_; } 0..$#$R; for my $I(0..$#$R ) { for my $J(0..$#$L ) { # if the @R line matches the @L line, based on # the key fields if($R->[$I]->[4] eq $L->[$J]->[1]) { # skip if we've already processed this @L # line next unless exists $L{$J}; # delete these lines from %L and %H so we # don't print them at the end delete $L{$J}; delete $R{$I}; # print fields 5 and 6 of the R line, and # fields 2 and 3 of the L line print join ',', @{ $R->[$I] }[4,5], @{ $L->[$J] }[1,2]; # go to next R line; this R line is already # matched last; } } } # print out the unmatched R lines, printing only fields # 5 and 6 print join ',', @{ $R->[$_] }[4,5,0,0] for keys %R; # print out the unmatched R lines, printing only fields # 2 and 3 print join ',', @{ $L->[$_] }[0,0,1,2] for keys %L; }