#csv #perl
#csv #perl
Вопрос:
Я пишу на perl, как вы можете записать в файл csv несколько переменных и поместить каждую из них в отдельную ячейку в одной строке. это часть моего кода:
#!/usr/bin/perl
use feature qw(say);
use strict;
use warnings;
use constant BUFSIZE => 6;
my $year = 1900;
my $input_file = 'pathZONE0.txt';
my $outputfile = 'pathoutputfile.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;
это приводит к размещению всех переменных рядом друг с другом в одной ячейке, чего я не хочу. можете ли вы помочь мне разделить переменные.
Комментарии:
1. вы можете использовать модуль Perl Text::CSV_XS для создания файла CSV вместо того, чтобы просто печатать их с помощью обработчика файлов.
2. Также для запроса — это приводит к размещению всех переменных рядом друг с другом в одной ячейке , вы можете объединить
@hexDevUID
содержимое массива запятой (,
) и сохранить его в скалярной переменной и распечатать в файле csv.3. Если вы напечатаете инструкцию печати, как вы делаете в
print FH $start, ' ' , print FH $DevType ...
, это добавит1
в печать, потому что успешная инструкция печати возвращает 1. Он также будет печатать сообщения в обратном порядке. Например.print "foo", print "bar"
фактически будет печататьbarfoo1
.4.
print join(",", @decimal[0,1,5,4,3,2]), "n";
может заменить последние 6 строк вашегоwhile
цикла. (Игнорирование значений в@hexDevType
, которые вы не используете в своем коде).
Ответ №1:
В файлах CSV нет ячеек. Я подозреваю, что вы открываете файл в программе для работы с электронными таблицами.
Секрет файла CSV заключается в том, что значения разделяются запятыми. Итак, вам нужно поставить запятые между любыми значениями, которые вы хотите отобразить в отдельных ячейках вашей электронной таблицы.
Похоже, что ваши данные находятся в @hexDevUID
. Самый простой способ — превратить это в строку, разделенную запятыми, используя join()
:
join(',', @hexDevUID)
Но более надежным подходом будет использование Text::CSV_XS.
Ответ №2:
Ниже приведен модифицированный операционный код, который не использует никаких CVS
модулей для вывода.
Добавлен код обработки ошибок для ошибки чтения и недостаточного количества прочитанных байтов для дальнейшей обработки.
use strict;
use warnings;
use feature 'say';
use constant BUFSIZE => 6;
my($buffer,$bytes_read);
my $infile = shift || 'pathZONE0.txt';
my $outfile = 'pathoutputfile.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("0xx",$_) } @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;
}
Цикл может быть переписан с использованием распаковки следующим образом
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 "0xx", $_ } @devUID;
say $out join(',',($start,$DevType,@hexDevUID));
} while ( $bytes_read );
Комментарии:
1. Спасибо за ваши усилия. Я добавлю обработку ошибок в свой код, поскольку он работает просто отлично. Однако это не то, что я просил, мне нужны файлы CSV, и мне нужно, чтобы мои данные были упорядочены по ячейкам. это то, с чем я борюсь в данный момент.
2. @waffles123 — Вы пытались открыть файл CSV в MS Excel, Open Office / Libre Office? Как только файл будет открыт, вы увидите данные в отдельных ячейках. Я надеюсь, что вы откроете файл как файл CSV.