while ( my ($lk, $lv) = each %$loc_file ) { if ( !exists( $$rem_file{$lk} or $$rem_file{$lk < $lv ) { # do a put... } elsif ( $lv < $$rem_file{$lk} ) { # do a get... } delete $$rem_file{$lk}; # harmless if it's non-existent } # at this point, the only elements remaining in %$rem_file # are files that do not exist on local host, so copy them all: for my $rk ( keys %$rem_file ) { # do a get... }