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

Monks - What is the best way to import a comma delimited file into an array or hash? I am tasked with taking one row out a series of comma delimited file to dump out into a single file. Thanks, Dave
  • Comment on Import comma delimited file into an array

Replies are listed 'Best First'.
Re: Import comma delimited file into an array
by jeffa (Bishop) on Nov 18, 2008 at 18:07 UTC

    If you aren't concerned with safety -- then just use split on a single comma -- you can even ignore whitespace:

    my @line = split( '\s*,\s*', $line );
    You'll end up with a new line in the last element of your array, but that can be chomped off.

    However, i strongly recommend using Text::CSV for this task (or Text::CSV_XS).

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      Now, if I import more than one row, don't I need to bind it?

        For that you need to consider an array of arrays, see perldsc.

Re: Import comma delimited file into an array
by ccn (Vicar) on Nov 18, 2008 at 18:09 UTC
      Here's my code if you want to take a look at it.
      use File::Glob; my @files = glob("C:/Wire/*.csv"); foreach my $x (@files) { open FILE, $x; while (<FILE>) { my @temp = split(/,/, $_); next if (substr($_,0,5) =~ /Debit/) ; print $_;} }
      right choice is this module Text::CSV
Re: Import comma delimited file into an array
by 23skiddoo (Beadle) on Nov 19, 2008 at 15:15 UTC
    I do a LOT of CSV parsing and like to use Text::Parsewords. With that, you can do something like:
    use Text::Parsewords; my $delim = ","; while (<>) { my @rec = &parse_line( $delim, 0, $_ ); # then do something with @rec... }
    Hope that helps!
    fnord
Re: Import comma delimited file into an array
by aquarium (Curate) on Nov 18, 2008 at 21:16 UTC
    if the primary goal is to filter, then use a command line grep and redirect the filtered output into a file; instead of reading every line into an array or hash and rejecting mostly.
    the hardest line to type correctly is: stty erase ^H
      I updated my code again. You will probably see what I'm trying to do. Let me know if there is a better or more efficient way of doing it.
      use File::Glob; my @files = glob("C:/Wire/*.csv"); open OUTPUT, ">C:/Wire/WO.txt"; foreach my $x (@files) { open FILE, $x; while (<FILE>) { my @row = split(/,/, $_); next if (substr($_,0,5) =~ /Debit/) ; print "{1100}02P N" . $row[6] . "{1110}" . "{1120}" . "{1510}" . " +{1520}" . "{3320}" . "{3400}" . "{3600}" . "{4320}" . "{5000}" . "\n"; print OUTPUT "{1100}02P N" . $row[6] . "{1110}" . "{1120}" . "{151 +0}" . "{1520}" . "{3320}" . "{3400}" . "{3600}" . "{4320}" . "{5000}" . "\n" } }
        Here are some improvements I would make:
        • use warnings; use strict;
        • Use lexical filehandles $fh.
        • Use the 3-argument form of open
        • Check the return value of open with die
        • Check for 'Debit' immediately
        • Use eq instead of a regex to check for 'Debit'
        • Just grab the 7th element from the array returned by split
        • Eliminate most of those concatenation operators
        • close the file
        use strict; use warnings; use File::Glob; my @files = glob("C:/Wire/*.csv"); for my $file (@files) { open my $fh, '<', $file or die "can not open file $file: $!"; while (<$fh>) { next if (substr($_,0,5) eq 'Debit'); my $row6 = (split /,/)[6]; print "{1100}02P N", $row6, "{1110}{1120}{1510}{1520}{3320}{3400 +}{3600}{4320}{5000}\n"; } close $fh; }
      And the hardest line to read correctly...ow.