Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

creating hash of hashes from input file

by chimiXchanga (Novice)
on Mar 03, 2017 at 10:15 UTC ( [id://1183546]=perlquestion: print w/replies, xml ) Need Help??

chimiXchanga has asked for the wisdom of the Perl Monks concerning the following question:

Hello! What I'm trying to achieve is to read the whole file and build a csv out of it, a record would be from Activity to next Activity, I did the header of the columns, but I don't know how to read the data and write it in the csv row by row. I had in mind to try and build a hash of hashes with each record and try and write it in csv format. //

Replies are listed 'Best First'.
Re: creating hash of hashes from input file
by poj (Abbot) on Mar 03, 2017 at 13:13 UTC

    Assuming the Activity code is unique within the data, and you want to preserve the column order and the record order try this ;

    #!perl use strict; use Data::Dumper; my $actid; my $key; my $last; my $colno = 0; my @order = (); my %cols = (); my %data = (); #my $infile = 'data.txt'; #open IN,'<',$infile or die "$!"; while (<DATA>){ #or IN chomp; next unless /\S/; # skip blank lines # continuation line if (! /:/){ $data{$actid}{$key} .= $_; next; } ($key,my $value)= split ':',$_,2; # create unique phone column if ($key eq 'Phone'){ $key = $last.' '.$key } $last = $key; if ( $key eq 'Activity' ){ $actid = $value; push @order,$actid; } $cols{$key} = ++$colno unless exists $cols{$key}; $data{$actid}{$key} = $value; } # close IN; print Dumper \%data; print Dumper \%cols; # output use Text::CSV; my $csv = Text::CSV->new ( { binary => 1 , eol => "\n", } ) or die "Cannot use CSV: ".Text::CSV->error_diag (); # col headings my @header = sort { $cols{$a} <=> $cols{$b} } keys %cols; print Dumper \@header; $csv->column_names(@header); # ouput records open my $fh, '>', "new.csv" or die "new.csv: $!"; $csv->print($fh,\@header); for my $actid (@order){ $csv->print_hr($fh, $data{$actid}); } close $fh or die "new.csv: $!"; __DATA__ Activity:C2012-0109 Type:COMBO ..

    Update : ++GotToBTru for duplicate phone columns

    poj
      This is amazing! Thank you!
Re: creating hash of hashes from input file
by GotToBTru (Prior) on Mar 03, 2017 at 13:46 UTC

    In general, this kind of problem is very easy to solve in Perl, but your data poses a few problems.

    1. You have multiple columns with the same name
    2. You have commas in your data
    You will need a more sophisticated data model than a simple hash, or a method for coming up with unique hash keys. The following is therefore simplistic but shows what can be done.

    use strict; use warnings; chomp(my $datafile = shift || 'data.file'); my $outputfile = 'output.file'; my @keys_in_display_order = qw/Activity Status Valuation/; my (%hash); open my $ifh, '<', $datafile; open my $ofh, '>', $outputfile; printf $ofh "%s\n", join '|', @keys_in_display_order; while(<$ifh>) { next unless $_; if (/^$keys_in_display_order[0]/) { print_it(); %hash = (); } $hash{$1} = $2 if (m/(.+):(.+)$/); } print_it(); close $ifh; close $ofh; sub print_it { return unless (%hash); printf $ofh "%s\n", join '|', @hash{@keys_in_display_order}; }
    cat output.file Activity|Status|Valuation C2012-0106|ISSUED|$339,784.94 C2012-0107|ISSUED|$306,963.74
    But God demonstrates His own love toward us, in that while we were yet sinners, Christ died for us. Romans 5:8 (NASB)

Re: creating hash of hashes from input file
by thanos1983 (Parson) on Mar 03, 2017 at 10:56 UTC
Re: creating hash of hashes from input file
by Anonymous Monk on Mar 03, 2017 at 10:34 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1183546]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2024-04-26 00:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found