The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Parse::CSV::Colnames - Highly flexible CSV parser including column names (field names) manipulation

NOTE

This Module derives from Parse::CSV by Adam Kennedy inheriting its methods. The main extensions are methods for column names manipulation and some simple method-fixes.

SYNOPSIS

Column names manipulation makes only sense if the fields-parameter is auto, i.e. column names are in the first line.

  # Parse a colon-separated variables file  from a handle as a hash
  # based on headers from the first line.
  my $objects = Parse::CSV::Colnames->new(
      handle => $io_handle,
      sep_char   => ';',
      fields     => 'auto',
   # select only rows where column name fieldname is "value"
      filter     => sub { if($_->{fieldname} eq "value") 
                       {$_} else 
                       {undef}
                        }
      );

  # get column names
  my @fn=$objects->colnames
  # you want lower case field names
  @fn=map {lc} @fn;
  # you want field names without blanks 
  @fn=map { s/\s+//g} @fn;
  # set column names
  $objects->colnames(@fn);

  while ( my $object = $objects->fetch ) {
      $object->do_something;
  } 

DESCRIPTION

This module is only an extension of Parse::CSV

For a detailed description of all methods see Parse::CSV

For a detailed description of the underlying csv-parser see Text::CSV_XS

Fixed METHODS

These methods don't work in the parent module Parse::CSV yet, because Adam Kennedy is very busy

combine

  $status = $csv->combine(@columns);

The combine method is provided as a convenience, and is passed through to the underlying Text::CSV_XS object. See example 3.

string

  $line = $csv->string;

The string method is provided as a convenience, and is passed through to the underlying Text::CSV_XS object. See example 3.

print

  $status = $csv->print($io, $columns);

The print method is provided as a convenience, and is passed through to the underlying Text::CSV_XS object. See example 1.

Added METHODS

fields

  @fields = $csv->fields;

The fields method is provided as a convenience, and is passed through to the underlying Text::CSV_XS object. It shows the actual row as an array.

colnames

  @colnames = $csv->colnames("fn1","fn2") # sets colnames
                  or
  @colnames = $csv->colnames; # gets colnames

The colnames method sets or gets colnames (=fields-param) So you can rename the colnames (hash-keys in Parse::CSV::Colnames object).

pushcolnames

  @colnames = $csv->pushcolnames("fn1","fn2") 

The pushcolnames method adds colnames at the end of $csv->colnames (=fields-param). You can do that if the filter-method adds some new fields at the end of fields-array in Parse::CSV::Colnames object . Please consider that these colnames or fields are not in the underlying Text::CSV_XS object.

EXAMPLES

You can test these examples with copy and paste

Example 1

Using csv->print

  #!/usr/bin/perl 

  use strict;
  use warnings;
  use Parse::CSV::Colnames;
  my $fh=\*DATA;
  my $fhout=\*STDOUT; # only for demo
  my $csv = Parse::CSV::Colnames->new(
                         #file => "testnamen.csv",
                         handle     => $fh,
                         sep_char   => ';',
                         fields     => 'auto',
                         binary     => 1, # for german umlauts and utf
                         filter     => sub { $_->{country}="Germany"; 
                                 $_->{product}=$_->{factor1}*$_->{factor2};
                                 # select only rows where column name product>0 
                                 if($_->{product}>0) {
                                         $_;
                                 } else {
                                         undef
                                 }
                        }
                         );
  $csv->pushcolnames(qw(product country));
  # get column names
  my @fn=$csv->colnames;
  # you want lower case field names
  @fn=map {lc} @fn;
  # you want field names without blanks
  map { s/\s+//g} @fn;
  # set column names
  $csv->colnames(@fn);

  # headerline for direct output
  $csv->print($fhout,[$csv->colnames]); # print header-line
  print "\n";


  while(my $line=$csv->fetch) {
        # csv direct output
        $csv->print($fhout,[$csv->fields,$line->{product},$line->{country}]); # only input-fields are printed with method fields
        print "\n";
  }

  __DATA__
  Name;Given Name;factor1;factor2
  Hurtig;Hugo;5.4;4.6
  Schnallnichts;Carlo;6.4;4.6
  Weissnich;Carola;7.4;4.6
  Leer;Hinnerk;0;4.6
  Keine Ahnung;Maximilian;8.4;4.6

Example 2

Building new fields by hand with map

  #!/usr/bin/perl 

  use strict;
  use warnings;
  use Parse::CSV::Colnames;
  my $fh=\*DATA;
  my $csv = Parse::CSV::Colnames->new(
                         #file => "testnamen.csv",
                         handle     => $fh,
                         sep_char   => ';',
                         fields     => 'auto',
                         binary     => 1, # for german umlauts
                         filter     => sub { $_->{country}="Germany"; 
                                 $_->{product}=$_->{factor1}*$_->{factor2};
                                 # select only rows where column name product>0 
                                 if($_->{product}>0) {
                                         $_;
                                 } else {
                                         undef
                                 }
                        }
                         );
  $csv->pushcolnames(qw(product country));
  # get column names
  my @fn=$csv->colnames;
  # you want lower case field names
  @fn=map {lc} @fn;
  # you want field names without blanks
  map { s/\s+//g} @fn;
  # set column names
  $csv->colnames(@fn);

  # headerline 2 fields
  my @outcolnames1=(qw(givenname product));
  print join(";",@outcolnames1) . "\n"; 


  while(my $line=$csv->fetch) {
        print join(";",map {$line->{$_}} @outcolnames1) . "\n"; 

  }

  __DATA__
  Name;Given Name;factor1;factor2
  Hurtig;Hugo;5.4;4.6
  Schnallnichts;Carlo;6.4;4.6
  Weissnich;Carola;7.4;4.6
  Leer;Hinnerk;0;4.6
  Keine Ahnung;Maximilian;8.4;4.6

Example 3

Using csv->combine and csv->string

  #!/usr/bin/perl 

  use strict;
  use warnings;
  use Parse::CSV::Colnames;
  my $fh=\*DATA;
  my $csv = Parse::CSV::Colnames->new(
                         #file => "testnamen.csv",
                         handle     => $fh,
                         sep_char   => ';',
                         fields     => 'auto',
                         binary     => 1, # for german umlauts
                         filter     => sub { $_->{country}="Germany"; 
                                 $_->{product}=$_->{factor1}*$_->{factor2};
                                 # select only rows where column name product>0 
                                 if($_->{product}>0) {
                                         $_;
                                 } else {
                                         undef
                                 }
                        }
                         );
  $csv->pushcolnames(qw(product country));
  # get column names
  my @fn=$csv->colnames;
  # you want lower case field names
  @fn=map {lc} @fn;
  # you want field names without blanks
  map { s/\s+//g} @fn;
  # set column names
  $csv->colnames(@fn);

  # headerline
  my @outcolnames2=(qw(name givenname product country));
  $csv->combine(@outcolnames2);
  print $csv->string . "\n";


  while(my $line=$csv->fetch) {
        # csv output
        $csv->combine(map {$line->{$_}} @outcolnames2);
        print $csv->string . "\n";


  }


  __DATA__
  Name;Given Name;factor1;factor2
  Hurtig;Hugo;5.4;4.6
  Schnallnichts;Carlo;6.4;4.6
  Weissnich;Carola;7.4;4.6
  Leer;Hinnerk;0;4.6
  Keine Ahnung;Maximilian;8.4;4.6

SUPPORT

Bugs should always be reported via the CPAN bug tracker at

http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Parse-CSV-Colnames

AUTHORS

Uwe Sarnowski <uwes at cpan.org>

Author of the parent modul Parse::CSV : Adam Kennedy

SEE ALSO

Parse::CSV, Text::CSV_XS

COPYRIGHT

Copyright 2011 Uwe Sarnowski

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

The full text of the license can be found in the LICENSE file included with this module.