in reply to Parse Contact File

I'd start with a split and use the fields it finds to put things in the hash. It might be better to use a regular expression, if that helps you validate input.

use strict; use warnings; use Data::Dumper; my %results; while (my $line = <DATA>) { chomp $line; my @fields = split /\s+/, $line, 4; $results{ $fields[0] }{ $fields[2] } = $fields[3]; } print Dumper \%results; __DATA__ 16XX27300 $ name John Doe 16XX27300 $ name2 Bla Bla 16XX27300 $ name3 275 Main ST 16XX27300 $ mlact 16H27300 16XX27300 $ addr 8TH Floor 16XX27300 $ city SAN Fran 16XX27300 $ state CA 16XX27300 $ zip 94111 16XX27301 $ name Jane Doe 16XX27301 $ name2 Bla Bla 16XX27301 $ name3 276 Main ST 16XX27301 $ name4 Tower 2 16XX27301 $ mlact 16XX27301 16XX27301 $ addr 8TH Floor 16XX27301 $ city SAN Fran 16XX27301 $ state CA 16XX27301 $ zip 94111

That produces a data structure like this:

$VAR1 = { '16XX27301' => { 'name2' => 'Bla Bla ', 'name' => 'Jane Doe ', 'name3' => '276 Main ST ', 'state' => 'CA ', 'city' => 'SAN Fran', 'zip' => '94111', 'name4' => 'Tower 2', 'mlact' => '16XX27301', 'addr' => '8TH Floor' }, '16XX27300' => { 'name2' => 'Bla Bla ', 'name' => 'John Doe ', 'name3' => '275 Main ST ', 'state' => 'CA ', 'city' => 'SAN Fran', 'zip' => '94111', 'mlact' => '16H27300', 'addr' => '8TH Floor' } };

You could get your CSV-ish output then from Text::CSV_XS.

One thing to beware of is that this reads the whole file into one large structure. If that's going to be a problem, you'd want to detect when you'd moved from one record to another and do output on a record-by-record basis instead of accumulating them all. Also, the hash does not maintain the order of the incoming records. If that's going to be an issue, you'd have to keep that order in a separate array or have a way to sort or something.

For more about hashes, see perldata. The above also uses hash references, which you could learn about in perlreftut or perlref.