Reputation: 19
I am coding in perl, how can you write into a csv file multiple variables and put each one in a separate cell in the same line. this a part of my Code:
#!/usr/bin/perl
use feature qw(say);
use strict;
use warnings;
use constant BUFSIZE => 6;
my $year += 1900;
my $input_file = 'path\ZONE0.txt';
my $outputfile = 'path\outputfile.csv';
open (my $BIN, "<:raw", $input_file) or die "can't open the file $input_file: $!";
my $buffer;
open(FH, '>>', $outputfile) or die $!;
while (1) {
my $bytes_read = sysread $BIN, $buffer, BUFSIZE;
die "Could not read file $input_file: $!" if !defined $bytes_read;
last if $bytes_read <= 0;
my @decimal= map { unpack "C", $_ } split //, $buffer;
my $start= $decimal[0];
my $DevType = $decimal[1];
my @hexDevType = sprintf("0x%x", $DevType);
my @DevUID =($decimal[5], $decimal[4], $decimal[3], $decimal[2]);
my @hexDevUID = map { sprintf("0x%x",$_) } @DevUID;
print FH $start, ' ' , print FH $DevType,' ', @hexDevUID , "\n";
}
close $BIN;
this results in puting all the variable next to each other in one cell, which is not what I want. can you help me separate the variables.
Upvotes: 0
Views: 254
Reputation: 6798
Bellow is modified OPs code which does not utilize any CVS
modules for output.
Added error handling code for read error and insufficient number of read bytes for further processing.
use strict;
use warnings;
use feature 'say';
use constant BUFSIZE => 6;
my($buffer,$bytes_read);
my $infile = shift || 'path\ZONE0.txt';
my $outfile = 'path\outputfile.csv';
open my $in, '<:raw', $infile
or die "Can't open $infile: $!";
open my $out, '+>>', $outfile
or die "Can't open $outfile: $!";
do {
$bytes_read = sysread $in, $buffer, BUFSIZE;
die "Error: read from $infile: $!" unless defined $bytes_read;
error_handler($bytes_read) unless $bytes_read == 6;
my @decimal = map { ord } split //, $buffer;
my($start,$DevType) = @decimal[0,1];
my @hexDevUID = map { sprintf("0x%02x",$_) } @decimal[5,4,3,2];
say $out join(',',($start,$DevType,@hexDevUID));
} while ( $bytes_read );
sub error_handler {
my $bytes = shift;
close $out;
close $in;
say "
Error: called error_handler(\$read_bytes)
Action: Emergency file closure to preserve data
Cause: Read insufficient $bytes bytes
" unless $bytes == 0;
exit $bytes ? 1 : 0;
}
The loop can be rewritten with use of unpack like following
do {
$bytes_read = sysread $in, $buffer, BUFSIZE;
die "Error: read from $infile: $!" unless defined $bytes_read;
error_handler($bytes_read) unless $bytes_read == 6;
my($start,$DevType,@devUID) = unpack('CCC4',$buffer);
my @hexDevUID = reverse map { sprintf "0x%02x", $_ } @devUID;
say $out join(',',($start,$DevType,@hexDevUID));
} while ( $bytes_read );
Upvotes: 1
Reputation: 69244
CSV files don't have cells. I suspect you're opening the file in a spreadsheet program.
The secret of a CSV file is that the values are separated by commas. So you need to put commas between any values that you want to appear in separate cells in your spreadsheet.
It looks like your data is in @hexDevUID
. The simplest way is to turn that into a comma-separated string using join()
:
join(',', @hexDevUID)
But the more robust approach will be to use Text::CSV_XS.
Upvotes: 4