my @output_cols = qw( name state location school birth birthplace ); my $csv_in = Text::CSV->new({ auto_diag => 1, binary => 1, }); my $csv_out = Text::CSV->new({ auto_diag => 1, binary => 1, eol => "\n", sep_char => "^", }); my %school_by_name; { open(my $fh_in, '<', 'dataa.txt') or die($!); $csv_in->column_names( $csv_in->getline($fh_in) ); while (my $row = $csv_in->getline_hr($fh_in)) { $school_by_name{ $row->{name} } = $row; } } open(my $fh_in, '<', 'datab.txt') or die($!); open(my $fh_out, '>', 'datac.txt') or die($!); $csv_in->column_names( $csv_in->getline($fh_in) ); $csv_out->print($fh_out, \@output_cols); while (my $row = $csv_in->getline($fh_in)) { my $name = $row->{name}; my $school_row = $school_by_name{$name} or die("Can't find school for $name\n"); %$row = ( %$school_row, %$row ); $csv_out->print($fh_out, [ @$row{@output_cols} ]); }