kumarkeyan has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I have to print the particular column from file. I have tried the below code
my @header=qw/studentrecord primary_ins primary_ins_type/; my @wanted_fields = @header; open(DATA, "sample_1.csv") or die "Could not open file $!"; my @fields = split /,/, <DATA>; chomp @fields; while (<DATA>) { chomp; my %row; @row{@fields} = split /,/; my @wanted_data = map {$row{$_}} @wanted_fields; print join(",", @wanted_data), "\n"; }
The above code is working fine if I give the field name in the header array(@header). But when I try to get the header value from file and assign that to @header, is not working properly.
open (FH, "< sample_1_header.csv") or die "Can't open file for read: $ +!"; my @header=<FH>; my $i=0; foreach(@header) { my @array=$header[$i]; print @array; my @wanted_fields = @array; open(DATA, "sample_1.csv") or die "Could not open file $!"; my @fields = split /,/, <DATA>; chomp @fields; #print Dumper \@fields; while (<DATA>) { chomp; my %row; @row{@fields} = split /,/; my @wanted_data = map {$row{$_}} @wanted_fields; print join(",", @wanted_data), "\n"; } $i++; }
And throws the below error. Use of uninitialized value $wanted_data[0] in join or string at samp_1.pl line 39, <DATA> line 98. Let me know your thoughts on this.

Replies are listed 'Best First'.
Re: Printing particular column is not working
by dasgar (Priest) on Jul 23, 2014 at 15:56 UTC

    Since it looks like your source file is a CSV, I'd recommend looking into using Text::CSV. Recently, I found Tie::Array::CSV, which does leverage Text::CSV and Tie::File but presents an interface that I personally like better than using Text::CSV directly.

Re: Printing particular column is not working
by AppleFritter (Vicar) on Jul 23, 2014 at 16:46 UTC

    Some example files would be nice. What do sample_1_header.csv and sample_1.csv contain? The script as you posted is working for me, sort of -- it's not throwing an error, at least, though it's not outputting anything either.

    Based on your code, I'm guessing that sample_1_header.csv contains a list of header fields that you're interested in, one per line. One thing that stands out to me is that you're not chomping these when you read them. Instead of this:

    my @header=<FH>;

    try this:

    chomp(my @header = <FH>);

    Making that change makes the script work for me.

    That said, here's a few more suggestions.

    • Format your code nicely. You'll improve readability, and that's gonna help you a lot later on.
    • use strict;
    • use warnings;
    • Use the three-argument form of open.
    • Use lexical filehandles ($FH instead of FH).
    • Avoid nested loops that both assign to $_. It's working here because the while loop's body doesn't use the foreach loop's $_ and because there's no code following the while loop that does, but it's still a bad idea.
    • $i is not necessary; get rid of it. Same for @array.
    • For that matter, @wanted_fields will only ever contain one field. Don't make it an array.

    I also concur with dasgar: don't reinvent the wheel, use a CPAN module to deal with CSV files.

Re: Printing particular column is not working
by fishmonger (Chaplain) on Jul 24, 2014 at 13:39 UTC
    my @header=<FH>;

    That slurps the entire file into the array, not just the first line.

    Try: my $header = shift <FH>;

    Or: my @header = split(/,/, shift <FH>);

    Or the better option as has already been suggested would be to use the Text::CSV module or one of its brethren.

Re: Printing particular column is not working
by tbone654 (Beadle) on Jul 24, 2014 at 13:53 UTC
    The only time you really need to use something special with a CSV file is if a field can contain a comma...
    If there are no comma's in the fields you can probably print fields from a .CSV very easily with a one-liner...
    perl -ne 'printf("%10s %s \n", (split/,/)[4], (split/,/[0]);' file.csv

      No need for 2 separate split statements.

      perl -ne 'printf("%10s %s \n", (split/,/)[4,0]);' file.csv