【问题标题】:Retrieve first row from CSV as headers using Text::CSV使用 Text::CSV 从 CSV 中检索第一行作为标题
【发布时间】:2014-01-11 05:55:11
【问题描述】:

我觉得我遗漏了一些相当明显的东西,但在文档中找不到任何答案。对使用 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;

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

【问题讨论】:

    标签: perl csv perl-module


    【解决方案1】:

    例如,几乎直接来自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 围绕后者。

    【讨论】:

      【解决方案2】:

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

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

      干杯

      【讨论】:

      • 你的第一个 while 循环,while (my $line = &lt;$data&gt;) 读入第一行数据但不打印出来。应该只使用第二个 while 循环。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-15
      • 1970-01-01
      • 2015-01-09
      • 1970-01-01
      • 2021-11-11
      相关资源
      最近更新 更多