Frage

I feel like I'm missing something rather obvious, but can't find any answers in the documentation. Still new to OOP with Perl, but I'm using Text::CSV to parse a CSV for later use.

How would I go about extracting the first row and pushing the values to array @headers?

Here's what I have so far:

#!/usr/bin/perl
use warnings;
use diagnostics;
use strict;
use Fcntl ':flock';
use Text::CSV;

my $csv = Text::CSV->new({ sep_char => ',' });
my $file = "sample.csv";
my @headers;        # Column names

open(my $data, '<:encoding(utf8)', $file) or die "Could not open '$file' $!\n";
while (my $line = <$data>) {
  chomp $line;

  if ($csv->parse($line)) {             
    my $r = 0;      # Increment row counter
    my $field_count = $csv->fields();       # Number of fields in row

    # While data exists...
    while (my $fields = $csv->getline( $data )) {
      # Parse row into columns
      print "Row ".$r.": \n";    

      # If row zero, process headers
      if($r==0) {
        # Add value to @columns array
        push(@headers,$fields->[$c]);
      } else {
        # do stuff with records...
      }         
  }
  $r++
}           
close $data;

You'd think that there would be a way to reference the existing fields in the first row.

War es hilfreich?

Lösung

Pretty much straight from the documentation, for example.

#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV_XS;

my $csv = Text::CSV_XS->new ({ binary => 1, eol => $/ });

my $file = 'o33.txt';
open my $io, "<", $file or die "$file: $!";

my $header = $csv->getline ($io);
print join("-", @$header), "\n\n";

while (my $row = $csv->getline ($io)) {
    print join("-", @$row), "\n";
}

__END__
***contents of o33.txt
lastname,firstname,age,gender,phone
mcgee,bobby,27,M,555-555-5555
kincaid,marl,67,M,555-666-6666
hofhazards,duke,22,M,555-696-6969

Prints:

lastname-firstname-age-gender-phone

mcgee-bobby-27-M-555-555-5555
kincaid-marl-67-M-555-666-6666
hofhazards-duke-22-M-555-696-6969

Update: Thinking about your problem, it may be that you want to address the data by its column name. For that, you might be able to use something (also from the docs), like this:

$csv->column_names ($csv->getline ($io));

while (my $href = $csv->getline_hr ($io)) {
    print "lastname is: ", $href->{lastname},
          " and gender is: ", $href->{gender}, "\n"
}

Note: You can use Text::CSV instead of Text::CSV_XS, as the former is a wrapper around the latter.

Andere Tipps

Thought I'd post my results for others.

#!/usr/bin/perl
use warnings;
use diagnostics;
use strict;
use Text::CSV;

sub read_csv {  
    my $csv = Text::CSV->new({ sep_char => ',' });
    my $file = shift;

    open(my $data, '<:encoding(utf8)', $file) or die "Could not open '$file' $!\n";

    # Process Row Zero
    my $header = $csv->getline ($data);
    my $field_count = $csv->fields();

    # Read the rest of the file
    while (my $line = <$data>) {
        chomp $line;

        # Read line if possible
        if ($csv->parse($line)) {             
            my $r = 0;

            # While data exists...
            while (my $fields = $csv->getline( $data )) {
                # Parse row into columns
                print Display->H2;
                print "Row ".$r.": ".@$fields." columns. \n";    

                # Print column values
                for(my $c=0; $c<@$fields; $c++) {
                    print @$header[$c]." : ".@$fields[$c]."\n";
                }
                $r++                                                        
            }
        }
        close $data;
    }
}

Cheers

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top