我有一组来自数据库的行,我想将其保存到csv文件中 考虑到数据是ascii chars而没有任何奇怪的字符,以下是否足够?
my $csv_row = join( ', ', @$row );
# save csv_row to file
我担心的是,这是否会创建任何工具都可以作为CSV接受的行,例如不关心引用等。
更新
这有什么不同吗?
my $csv = Text::CSV->new ( { binary => 1, eol => "\n"} );
my $header = join (',', qw( COL_NAME1 COL_NAME2 COL_NAME3 COL_NAME4 ) );
$csv->print( $fh, [$header] );
foreach my $row ( @data ) {
$csv->print($fh, $row );
}
这让我成为第一行:
" COL_NAME1,COL_NAME2,COL_NAME3,COL_NAME4"
请注意双引号,其余行没有任何引号
与我的join
有什么区别?我还需要binary
设置吗?
答案 0 :(得分:2)
最安全的方法应该是用逗号分隔符编写干净的记录。越简单越好,特别是在现实生活中有如此多变化的格式。如果需要,请双引号。
使用该模块的真正优势在于阅读"现实生活"数据。但是,使用它进行书写也是非常有意义的,因为统一的CSV方法。此外,可以以清晰的方式设置选项,模块可以解决数据中的一些故障。
Text::CSV文档告诉我们binary
选项
重要说明:默认行为是仅接受
0x20
(空格)到0x7E
(代字号)范围内的ASCII字符。这意味着字段不能包含换行符。如果您的数据包含字段中嵌入的换行符,或0x7E
(代字号)或二进制数据上方的字符,则 必须 在通话中设置binary => 1
到new
。要覆盖最广泛的解析选项,您始终需要设置二进制文件。
我说要用它。由于您编写文件,因此可以选择此选项,以及eol
(或使用say
方法)。但请扫描许多有用的选项并查看他们的defaults。
对于标头,print
方法需要一个数组引用,其中每个字段都是一个元素,而不是一个带逗号分隔字段的字符串。所以说
my $header = join (',', qw(COL_NAME1 COL_NAME2 COL_NAME3 COL_NAME4)); # WRONG
$csv->print( $fh, [$header] );
因为$header
是一个字符串,然后它成为[ ... ]
创建的(匿名)数组引用的唯一元素。因此,它将此字符串打印为行中的第一个字段,并且由于它在其中检测到分隔符,
本身,它也会双引号。相反,你应该
$csv->print($fh, [COL_NAME1 COL_NAME2 COL_NAME3 COL_NAME4]);
或者更好地将列名分配给@header
,然后执行$csv->print($fh, \@header)
。
这也是为什么使用模块进行写入的好例子 - 如果逗号滑入数组的元素,应该是单个字段,则通过双引号正确处理。
一个完整的例子
use warnings;
use strict;
use Text::CSV_XS;
my $csv = Text::CSV->new ( { binary => 1, eol => "\n" } )
or die "Cannot use CSV: " . Text::CSV->error_diag();
my $file = 'output.csv';
open my $fh_out , '>', 'output.csv' or die "Can't open $file for writing: $!";
my @headers = qw( COL_NAME1 COL_NAME2 COL_NAME3 COL_NAME4 );
my @data = 1..4;
$csv->print($fh_out, \@headers);
$csv->print($fh_out, \@data);
close $fh_out;
生成文件output.csv
COL_NAME1,COL_NAME2,COL_NAME3,COL_NAME4 1,2,3,4