BlueStarry
BlueStarry

Reputation: 717

Text::Csv module in perl, writing data inside a csv

In the synopsis of Text::CSV there's this example

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, "<:encoding(utf8)", "test.csv" or die "test.csv: $!";

while ( my $row = $csv->getline( $fh ) ) {
    $row->[2] =~ m/pattern/ or next; # 3rd field should match
    push @rows, $row;
}

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

$csv->eol ("\r\n");

open $fh, ">:encoding(utf8)", "new.csv" or die "new.csv: $!";
$csv->print ($fh, $_) for @rows;
close $fh or die "new.csv: $!";

I see that it pushes some rows on the array @rows, and then the array gets printed line by line inside the output file.

I need to do a similar thing (like checking for a pattern and then save the row to rewrite it on another file later) but I need just one field from each row, and I need to add new fields to the $row that is been pushed. How would I do that?

Upvotes: 0

Views: 635

Answers (1)

Borodin
Borodin

Reputation: 126722

It's hard to offer a solution when your requirement is so vague, but the general principle is that, instead of pushing $row onto the @rows array, you should push a reference to an array containing the data that you want in the output. It's convenient to use an anonymous array for this

Suppose you want the output to be A, followed by the third column from the row, followed by Z. Then you would change the while loop like this

You will have to change the test to make the check that you want

while ( my $row = $csv->getline($fh) ) {
    next unless $row->[2] =~ /pattern/;
    push @rows, [ 'A', $rows->[2], 'Z' ];
}

Upvotes: 1

Related Questions