my %cat2s_by_cat1; while (<$fh2>) { chomp; my ($cat1, $cat2) = split /=/; push @{ $cat2s_by_cat1{$cat1} }, $cat2; } while (<$fh1>) { chomp; my ($dog, $bird, $cat1) = split /=/; exists( $cat2s_by_cat1{$cat1} ) or die; for my $cat2 ( @{ $cat2s_by_cat1{$cat1} } ) { print $fh_out (join('=', $dog, $bird, $cat1, $cat2), "\n"); } }