Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

A couple of notes:

  • All three lists of my variables are identical
  • The keys of the big %hash are almost identical to the long print $OUTPUT "..." (only two whitespace and capitalization differences - one of them is causing a bug in your code: in the hash it's 'Asset Application ID' but later you say $$ref2{'Asset Application Id'})
  • The last two for loops are identical except for the variables being looped over (could be combined as for (@output_array, @extras))

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:

  • The = vs eq bugs noted by AnomalousMonk fixed
  • The precedence issue in open ... || die fixed
  • Output code added
  • I changed push @extras,\$ref; to push @extras,$ref2; because that made more sense to me, although I'm not sure about it

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.


In reply to Re: Searching between two hashes by haukex
in thread Searching between two hashes by TStanley

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (3)
As of 2024-04-19 22:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found