我有一个perl脚本可以很好地打印到屏幕上但是当我尝试将输出重定向到csv文件时,我收到以下错误:Expected fields to an array ref
。我使用的是Text::CSV_XS
,错误的行是$csv->print ($fh, $_) for @rows;
#!/user/local/bin/perl
use Text::CSV_XS;
$|=1;
sub main {
print "Enter file to process: ";
my $file = <STDIN>;
chomp $file;
my @rows;
my $csv = Text::CSV_XS->new ({ binary => 1, auto_diag => 1 });
open(INPUT, $file) or die("Input file $file not found.\n");
while(my $line = <INPUT>) {
if($line =~ /Assay/) {
@words = split(" ",$line);
push @rows, $words[1];
}
if($line =~/Date/) {
@words = split(" ",$line);
push @rows, $words[1];
push @rows, $words[2];
}
if($line =~/Patient/) {
@words = split(" ",$line);
push @rows, $words[0];
push @rows, $words[1];
push @rows, $words[2];
}
if($line =~/channel_index/) {
print $line;
}
if($line =~/Channel/) {
@words = split(" ",$line);
push @rows, $words[1];
push @rows, $words[2];
}
if($line =~/DCMean/) {
@words = split(" ",$line);
push @rows, $words[0];
push @rows, $words[1];
}
}
$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: $!";
close(INPUT);
}
main();
答案 0 :(得分:4)
你将价值推向@rows
的方式,你只需要获得一个庞大,平坦的标量阵列。这可能不是你想要的。
请考虑以下事项:
my @rows;
push @rows, 'a';
push @rows, 'b';
push @rows, 'c';
push @rows, 'd';
push @rows, 'e';
push @rows, 'f';
给我们一个平面阵列:[a,b,c,d,e,f]
。
这是:
my @rows;
push @rows, ['a', 'b', 'c'];
push @rows, ['d', 'e', 'f'];
给我们一个嵌套数组:[[a,b,c], [d,e,f]]
。
同样,数组和arrayrefs类似,但不同。见perlreftut。这是一个微妙的概念,但对于高级Perl开发至关重要。请阅读并理解它!
您的推送代码可能如下所示:
push @rows, [$words[1], $words[2]];
这些标量周围的[]
会创建一个匿名数组引用。由于@rows
现在将填充数组引用,因此您不需要更改任何其他内容。
答案 1 :(得分:1)
尝试将错误报告行更改为以下内容:
$csv->print ($fh, \@rows);
来自Text::CSV_XS
功能
print
CPAN文档的引用
它期望数组引用作为输入(不是数组!)