Ghost
Ghost

Reputation: 3966

Issues while creating CSV out of an array in Perl

Brief Description of my problem:

I have an array which needs to be converted to CSV. I am facing problems with the desired output, and not the conversion itsef.

My Code:

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

my (@first_set, @final_set); 
my $file = do {
    open my $fh, '<', '<file_name>.txt' or die "Unable to open file for input: $!";
    local $/;
    <$fh>;
};

@first_set = ( $file =~ m/<regex>/g)  ;
while ( @first_set ) {
    @final_set = splice @first_set, 0, 26;
    open(my $output, '>', 'mpc7_file.csv') or die "Couldn't open file file.csv, $!";
    my $csv = Text::CSV -> new ( { sep_char => ",", eol => "\n", binary => 1, quote_char => undef } );
    foreach my $element ( @final_set ) { 
        $csv -> print ( \*$output, \@final_set );
    }   
    close($output) or die "Couldn't close file properly";
}

Contents of @final_set:

10:38:49 788 56 51 56 61 56 59 56 51 56 80 56 83 56 50 45 42 45 50 45 50 45 43 45 54
10:38:51 788 56 51 56 61 56 59 56 51 56 80 56 83 56 50 45 42 45 50 45 50 45 43 45 54

Contents of the CSV file:

10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54

Desired Output:

My CSV file should contain the @final_set (each element separated by comma).

10:38:49,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54
10:38:51,788,56,51,56,61,56,59,56,51,56,80,56,83,56,50,45,42,45,50,45,50,45,43,45,54

Question:

Where am I going wrong? I'm not really able to understand my mistake. Please help.

EDIT:

Even if I move the CSV file creation block outside of while loop, the output is still the same.

Upvotes: 0

Views: 51

Answers (1)

Borodin
Borodin

Reputation: 126772

Okay I see what you're doing. The problem is that @final_set changes each time around the while loop, and whether you declare it globally like that or locally as you should you still need to print its contents each time it changes

There's also no need to use Text::CSV with such simple data. As you can see, every variable is declared at its point of first use, which is best practice in most languages

use strict;
use warnings;

my $in_file  = '<file_name>.txt';
my $out_file = 'mpc7_file.csv';

my $data = do {
    open my $fh, '<', $in_file or die qq{Unable to open "$in_file" for input: $!};
    local $/;
    <$fh>;
};

my @first_set = $data =~ /<regex>/g;

open my $out_fh, '>', $out_file or die qq{Unable to open "$out_file" for output: $!};

while ( @first_set ) {
    my @final_set = splice @first_set, 0, 26;
    print $out_fh join(',', @final_set), "\n";
}

close $out_fh or die qq{Unable to close "$out_file": $!};

Upvotes: 2

Related Questions