0

I'm new to Perl. This is a sample csv entry similar to mine. I would like to parse this, tried briefly Text::CSV, but no luck. The issue here is newline and commas inside fields. How could I parse this file in Perl? Thanks for the help.

1,A,"Length of x, where x is y"
2,B,"Set A to “10”, an invalid state"
3,C,"Solve
A+B and
B+A
"
4,D, Set C to B
dgw
  • 13,418
  • 11
  • 56
  • 54
Vikyboss
  • 940
  • 2
  • 11
  • 23
  • 6
    Show the code you tried. It can probably be made to work Text::CSV is a good module – Cfreak Mar 29 '12 at 18:24
  • The best clue is ... don't try to parse CSV by yourself. Why do you think that `Text::CSV` did not work? – dgw Mar 29 '12 at 18:38
  • Sorry about that the post, I figured out the solution. I have posted it. Initially I was trying to parse myself, but later looked into Text::CSV but the issue was due to the option that I didn't include. Sorry and Thanks. – Vikyboss Mar 29 '12 at 18:51

2 Answers2

7

This code (taken directly from Text::CSV documentation):

#!/usr/bin/perl

use strict;
use Text::CSV;
use Data::Dumper;


my $rows;
my $csv = Text::CSV->new ( { binary => 1 } )  # should set binary attribute.
                 or die "Cannot use CSV: ".Text::CSV->error_diag ();

open my $fh, "<", "test.csv" or die "test.csv: $!";

while ( my $row = $csv->getline( $fh ) ) {
     push @{$rows}, $row;
}

$csv->eof or $csv->error_diag();

close $fh;

# This gets rid of spaces at start and end of string 
# as well as newlines within the fields.
for ( 0 .. scalar @{$rows}-1 ) {
    $rows->[$_][2] =~ s/^\s*//;
    $rows->[$_][2] =~ s/\n/ /gms;
}

print Dumper($rows);

Produces the following output:

$VAR1 = [
          [
            '1',
            'A',
            'Length of x, where x is y'
          ],
          [
            '2',
            'B',
            'Set A to “10”, an invalid state'
          ],
          [
            '3',
            'C',
            'Solve A+B and B+A '
          ],
          [
            '4',
            'D',
            'Set C to B'
          ]
        ];

Which (I'm guessing) is what you want to achieve.

user1269651
  • 184
  • 8
0

Thanks Everyone who commented, I figured it out. The thing I didn't do was

{ binary => 1, eol => $/ }

Here is the working code:

#!/usr/bin/perl

use 5.010;
use strict;
use warnings;
use Text::CSV;

open(my $Fh, "<", 'datalane_csr.csv');

my $csv = Text::CSV->new ({ binary => 1, eol => $/ });
while (my $row = $csv->getline ($Fh)) {
  say @$row[2];
  }

close(CSV);

Thanks once again. And sorry for the post.

But I have a small issue, the '"' is shown as wierd characters when I print them.

Vikyboss
  • 940
  • 2
  • 11
  • 23