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.
精彩评论