# first, scan the first file, noting the file pos's on which each key occurs. my %key_pos_in_first_file; # key=key, val=array of file positions. open F1, "+< $first_file" or die "open $first_file for random read - $!\n"; my $p1 = 0; while () { chomp; my @l = split /\|/; push @{ $key_pos_in_first_file{ $l[0] } }, $p1; $p1 = tell F1; } # second, go through the second file, joining. open F2, "< $second_file" or die "open $second_file for read - $!\n"; while () { chomp; my @l2 = split /\|/; # go to each pos in the first file and use that line for my $p1 ( @{ $key_pos_in_first_file{ $l2[0] } } ) { seek F1, $p1, 0; my $l1 = ; chomp $l1; my @l1 = split /\|/, $l1; # join print "@l2 - @l1\n"; } } close F2; close F1;