开发者

Why do I get the error message »Failed to parse line« with Text::CSV?

I'm trying to parse a CSV file in Perl, but don't really understand examples I found on the Internet. Could someone explain me this example?

#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;

my $file = 'dhcp.csv';

my $csv = Text::CSV->new();

open (CSV, "<", $file) or die $!;

while (<CSV>) {
    next if ($. == 1);
    if ($csv->parse($_)) {
        my @columns = $csv->fields();
        print "Name: $columns[0]\n\tContact: $columns[4]\n";
    } else {
        my $err = $csv->error_input;
        print "Failed to parse line: $err";
    }
}
close CSV;

When I run it, I get Failed to parse line. What does the $. stand for? And $_?

My goal is to find the line where there is the computer name I search for. After that, I can find the corresponding MAC address. I hope this is comprehensible, thanks.


EDIT:

My CSV file looks like:

172.30.72.22,DEC-16.rec.local,001676b755d6,Bart SIMPSONS,Ordinateur de bureau,DEC/DECVA,002,SR2 0.12,,Accès complet,N/D,Aucun
172.30.72.23,DEC-20.rec.local,001688b7bfdc,Larry Wall,Ordinateur de bureau,DEC/DECVA,003,?,,Accès complet,N/D,Aucun

Field #2 is the hostname, I want to resolve field #3 (MAC address) by field #2.


EDIT n°2:

In fact, don't need to parse the CSV file for my purpose. I found a bash solution, fast enough for my application.

my $macAdd = `cat dhcp.csv | grep {computerName} | cut -d ',' -f 5`

Done !

Thanks for y开发者_如何学Pythonour help, one day I'll have to parse a csv file, sure.

3rd edit : don't know who edited my post and the topic question, but that's not it at all !


$. is input line number. $_ is the "magic" default variable which many Perl operators (including <>) act upon unless instructed otherwise.

Look them up in perldoc perlvar for details.

BTW if you stuff $. into the error message you'll at least know which line fails.

EDIT: I replaced error_input with error_diag and now it says: 2037EIF - Binary character in unquoted field, binary off106. After adding my $csv = Text::CSV->new ({binary=>1}); the lines parsed OK.

So it looks like the accented characters confused Text::CSV.


It is good practice in these days making script utf-8 compliant, so:

use strict;
use warnings;
use Carp;
#use utf8; #uncomment, if in this script want use utf8 characters
use Text::CSV;

my $csv = Text::CSV->new();

my $file = 'dhcp.csv';
open(my $fh, "<:encoding(UTF-8)", $file) || croak "can't open $file: $!";
while (<$fh>) {
    #next if ($. == 1); #uncomment, if your data file has header line too
    if ($csv->parse($_)) {
        my @columns = $csv->fields();
        print "Name: $columns[0]\n\tContact: $columns[4]\n";
    } else {
        my $err = $csv->error_input;
        print "Failed to parse line: $err";
    }
}
close $fh;


You could try using the $csv->error_diag method to find out what the module doesn't like about your input.

And then you could turn on binary data handling to get it working. But I strongly suspect you should be looking at Text::CSV::Encoded instead.


I disagree with the folks about using your own CSV parser. Instead, my suggestion is to use a simpler CSV parser like Parse::CSV. It's an easy-to-use module. The very first example in the documentation should be enough to give you a painless start.


It is always good to open CSV files in binary mode:

my $csv = Text::CSV->new({ binary => 1});

May be your CSV file is encoded in UTF8 or any other charset. Read Text::CSV documentation for more info.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜