#!/usr/bin/perl package main; use 5.006_000; use diagnostics; use strict; use warnings; sub escape($) { my ($value) = @_; # if line contains a comma or " we have to quote the contents if ($value =~ /[",]/) { # escape " characters by replacing each with two " characters $value =~ s/"/""/g; $value = '"' . $value . '"'; } return $value; } sub parse($$) { my ($in_file_name, $out_file_name) = @_; my $records_hash_ref = {}; my $record_ref = undef; my $line_count = 0; my $record_count = 0; # read the records from the output file in our custom format open(FH_IN, "< $in_file_name") or die "Couldn't read file '$in_file_name': $!\n"; my $line; while (defined($line = )) { $line_count++; chomp $line; if ($line =~ /^\s*$/) { # blank line } else { # extract data from line by removing leading and trailing spaces and looking for "field: value" $line =~ s/^\s+//; $line =~ s/\s+$//; if ($line =~ /^(\w+):\s*(.*)$/) { my $field = $1; my $value = $2; if (($field ne 'Name') && (!defined($record_ref))) { print("WARNING: must specify a name before using any other field in input file, line #$line_count: '$line'.\n"); } elsif ($field eq 'Name') { $record_ref = $records_hash_ref->{$value}; if (!defined($record_ref)) { $record_count++; $record_ref = {}; $record_ref->{'Name'} = $value; $records_hash_ref->{$value} = $record_ref; } else { print("WARNING: duplicate record name '$value' in input file line #$line_count: '$line'.\n"); } } elsif (($field eq 'Email') || ($field eq 'Address') || ($field eq 'Completed_the_Test')) { # Set the field of the current record to the specified value if (!defined($record_ref->{$field})) { $record_ref->{$field} = $value; } else { print("WARNING: redefined field '$field' in input file line #$line_count: '$line'.\n"); } } else { print("WARNING: unrecognized field '$field' in input file line #$line_count: '$line'.\n"); } } else { print("WARNING: unparsed input file line #$line_count: '$line'.\n"); } } } close(FH_IN); print("$record_count records loaded from $line_count lines in '$in_file_name'.\n"); # write the records to the output file in CSV format open(FH_OUT, "> $out_file_name") or die "Couldn't write file '$out_file_name': $!\n"; foreach my $name (sort keys %{$records_hash_ref}) { $record_ref = $records_hash_ref->{$name}; my $first = 1; foreach my $field ('Name', 'Email', 'Address', 'Completed_the_Test') { if ($first) { $first = 0; } else { print FH_OUT ","; } print FH_OUT escape($record_ref->{$field}); } print FH_OUT "\n"; } close(FH_OUT); print("$record_count records written as $record_count CSV lines to '$out_file_name'.\n"); } parse("test_records.txt", "test_records.csv");