Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

parsing CSV with TEXT::CSV

by GertMT (Hermit)
on Jul 21, 2009 at 20:21 UTC ( [id://782071]=perlquestion: print w/replies, xml ) Need Help??

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

hi Monks,
Trying to make a little csv-parsing script more efficient. Everything works fine. I realize my current set-up is going to look really ugly if I add more "selection-rules" for a change in value of column 2. I chose current setup as I'm using regexes for the real data but I'm losing track of all the curly braces at the end of my script.

Is there a different way of setting the selections up? Via subs? Eg. if I'd like to add "boat" after "Sailing".
Thanks,
Gert
#!/usr/bin/perl -w use strict; use diagnostics; use Text::CSV_XS qw( ); my $qfn_in = 'data.txt'; open( my $fh_in, '<', $qfn_in ) or die("Can't open file \"$qfn_in\": $!\n"); my $fh_out = \*STDOUT; my $csv_in = Text::CSV_XS->new( { sep_char => ',', eol => $/ } ); my $csv_out = Text::CSV_XS->new( { eol => $/ } ); my $selection = "Apple"; my $code = " ####"; my $filter = "CX89"; while ( my $row = $csv_in->getline($fh_in) ) { if ( $row->[1] eq $selection ) { $code = "tree"; if ( $row->[0] eq $filter ) { $fh_out->print("$row->[0] $row->[1] $code \n"); } } }
data.txt
"CX89",Apple "CX89",Sailing "CX89",Apple "AC75",Apple "CX89",Sailing

Replies are listed 'Best First'.
Re: parsing CSV with TEXT::CSV
by Anonymous Monk on Jul 22, 2009 at 13:12 UTC
    CX89 Apple tree
    CX89 Sailing boat
    CX89 Apple tree
    AC75 Apple candy
    CX89 Sailing boat
    #!/usr/bin/perl -- use strict; use warnings; use diagnostics; use Text::CSV; use Text::CSV_XS qw( ); #main { use autodie 2.06; open( my $fh_in, '<', 'data.txt' ); my $col_rules = [ [ [ 1 => eq => 'Apple'], [ 0 => eq => 'CX89'], [ "%s %s tree\n" => [ 0, 1 ] ], ], [ [ 1 => eq => 'Sailing'], [ 0 => eq => 'CX89'], [ "%s %s boat\n" => [ 0, 1 ] ], ], [ [ 0 => ne => 'CX89'], [ 1 => eq => 'Apple'], [ 1 => ne => 'Sailing'], [ "%s %s candy\n" => [ 0, 1 ] ], ], ]; process_rules( $col_rules, $fh_in, \*STDOUT ); } sub process_rules { my ( $rules, $in, $out ) = @_; my $csv_in = Text::CSV->new( { sep_char => ',', eol => $/ } ) or die Text::CSV->error_diag(); my $csv_out = Text::CSV->new( { eol => $/ } ) or die Text::CSV->error_diag(); while ( my $row = $csv_in->getline($in) ) { my $rulematch = 0; for my $ruleset (@$rules) { last if $rulematch; my $ruleset_match = 0; for my $rule ( @$ruleset[0 .. $#$ruleset ] ) { my ( $ix, $op, $val ) = @$rule; $ruleset_match++ if $op eq 'eq' and $val eq $row->[$ix]; $ruleset_match++ if $op eq 'ne' and $val ne $row->[$ix]; } #~ warn '$rulematch ',$rulematch; #~ warn '$ruleset_match ', $ruleset_match ; #~ warn '$#$ruleset ', $#$ruleset ; if ( $ruleset_match == $#$ruleset ) { $rulematch++; my ( $printf, $indices ) = @{ $ruleset->[-1] }; $out->printf( $printf, (@$row)[@$indices] ); } } } } __DATA__ "CX89",Apple "CX89",Sailing "CX89",Apple "AC75",Apple "CX89",Sailing
      This code is for me definitely worth to study in detail. It brings me a step further in my goal and learning process. Right now trying to sort out what this autodie module is all about.
      Many thanks!
      Gert
        autodie stops you from having to write
        open(...) or die; close ... or die;
        and allows you to use eval{} to trap fatal errors
        eval { open ...; open ...; 1 } or print "ERROR $@\n";

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://782071]
Approved by jrsimmon
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-16 19:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found