Retrieve first row from CSV as headers using Text::CSV
Solution 1
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.
Solution 2
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
Ryan Dunphy
Always learning, always optimizing, always automating.
Updated on July 25, 2022Comments
-
Ryan Dunphy almost 2 years
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.
-
Chris Charley over 10 yearsYour first while loop,
while (my $line = <$data>)
reads in the first data line but does not print it out. Only the second while loop should be used instead.