使用Text :: CSV从CSV中检索第一行作为标题

时间:2013-12-23 02:44:02

标签: perl csv perl-module

我觉得我错过了一些相当明显的东西,但在文档中找不到任何答案。对于使用Perl的OOP来说仍然是新手,但我正在使用Text :: CSV来解析CSV以供日后使用。

如何提取第一行并将值推送到数组@headers?

这是我到目前为止所拥有的:

#!/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;

您认为有一种方法可以引用第一行中的现有字段。

2 个答案:

答案 0 :(得分:10)

非常直接来自documentation,例如。

#!/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

打印:

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

更新:考虑到您的问题,可能是您希望按列名称来处理数据。为此,您可以使用某些东西(也来自文档),如下所示:

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

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

注意:您可以使用Text::CSV代替Text::CSV_XS,因为前者围绕后者a wrapper

答案 1 :(得分:0)

以为我会将结果发布给其他人。

#!/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;
    }
}

干杯