in reply to Searching between two hashes
A couple of notes:
That's a lot of deduplication that could be done. In order to be able to test, I made a few changes to your code:
I admit I don't quite understand the logic going on in the loops over @input_array and @output_array, because they produce a lot of repeated output (more fitting variable names would also help), perhaps you want to use a hash for lookups instead of nested loops. In that case, perhaps you don't need to slurp all of VHC-DVTPump.csv into memory, but could process it line-by-line.
But anyway, the main point I wanted to make was not to understand the logic for now, but to reduce the duplication and use Text::CSV (also install Text::CSV_XS for speed). I think in this case Text::CSV's column_names, getline_hr, and print_hr are very useful. With some fake input data, the following produces the same output as your code modified as I described, hopefully it's a starting point:
#!/usr/bin/env perl use warnings; use strict; use Text::CSV; my @COLUMNS = ("Asset Name","Asset Application ID","Serial Number", "Asset Type","Activity Status","Business Status","Description", "Primary Category","Category 1","Category 2","Category 3", "Department 1","Department 2","Department 3","Department 4", "Department 5","Department 6","Group 1","Group 2","Network ID 1", "Tag Type 1","Tag Classification 1","Tag Protected 1", "Tag Duress 1","Network ID 2","Tag Type 2", "Tag Classification 2","Tag Protected 2","Tag Duress 2","Map ID", "Gateway Group","X","Y","Z","NIST Certification Due Date", "Rental Return Date","Escalation3","NIST Certificate", "Escalation2","NIST Tag","ContactName","Escalation1", "PM Completed","Rental In User","last column","EOL"); sub read_csv { my ($filename,$cols) = @_; my $csv = Text::CSV->new({ binary=>1, auto_diag=>2 }); $csv->column_names($cols); open my $fh, '<', $filename or die "$filename: $!"; my $data = $csv->getline_hr_all($fh); $csv->eof or $csv->error_diag; close $fh; return $data; } my $out_filename = 'output.csv'; my $transfers = read_csv('transfers.csv', [qw/ MAC Serial ID /]); my $assets = read_csv('VHC-DVTPump.csv', \@COLUMNS); my @extra_assets; for my $trans (@$transfers) { for my $asset (@$assets) { if ( $$trans{'ID'} eq $$asset{'Asset Application ID'} && $$asset{'Network ID 1'} eq '' ) { $$asset{'Network ID 1'} = $$trans{'MAC'}; } else { push @extra_assets, $asset; } } } my $out_csv = Text::CSV->new({ binary=>1, auto_diag=>2, eol=>$/ }); $out_csv->quote_char(''); # to make output identical (I'd remove this) $out_csv->column_names(@COLUMNS); open my $out_fh, '>', $out_filename or die "$out_filename: $!"; $out_csv->print($out_fh, \@COLUMNS); for my $asset (@$assets, @extra_assets) { $out_csv->print_hr($out_fh, $asset); } close $out_fh;
By the way, my understanding is that your input files don't contain a header row, but your output file does? If that's not correct and your input file(s) also contain a header row, note that you could do away with the arrays of column names in the code entirely and use Text::CSV's header function instead.
|
|---|