将行保存为csv格式

时间:2017-08-11 07:07:48

标签: perl csv

我有一组来自数据库的行,我想将其保存到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设置吗?

1 个答案:

答案 0 :(得分:2)

最安全的方法应该是用逗号分隔符编写干净的记录。越简单越好,特别是在现实生活中有如此多变化的格式。如果需要,请双引号。

使用该模块的真正优势在于阅读"现实生活"数据。但是,使用它进行书写也是非常有意义的,因为统一的CSV方法。此外,可以以清晰的方式设置选项,模块可以解决数据中的一些故障。

Text::CSV文档告诉我们binary选项

  

重要说明:默认行为是仅接受0x20(空格)到0x7E(代字号)范围内的ASCII字符。这意味着字段不能包含换行符。如果您的数据包含字段中嵌入的换行符,或0x7E(代字号)或二进制数据上方的字符,则 必须 在通话中设置binary => 1new。要覆盖最广泛的解析选项,您始终需要设置二进制文件。

我说要用它。由于您编写文件,因此可以选择此选项,以及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