如何在Perl中使用不等长度数组创建CSV文件?

时间:2009-11-19 21:06:34

标签: perl excel csv

我必须解析一个文件,以便将其导入excel。所以,我认为最好的方法是创建一个csv文件。在此文件中,我必须将内容划分为不同的类别,并将它们表示在不同的列中。所以,我已经解析了文件以创建与类别对应的不同数组。现在,我正在尝试使用这些数组创建一个csv文件(考虑使用for循环)。但问题是,数组的长度不等

INPUT

NM_144736.3
NM_144963.1
XM_144975.2
BC144986.1
NM_144989.1
BC145001.1
XM_145018.2
NM_145015.2
XM_030711.2
AK145024.1
AK145030.1
NM_145034.1

我使用正则表达式将数据解析为不同的数组。所有NM到@ array1,XM到@ array2,BC到@ array3,AK到@ array4。 如果创建数组不是一个好主意,请让我知道是什么?我怎样才能从上面的数据中生成csv文件。

编辑:

输出

NM_144963.1,XM_144975.2,BC144986.1,AK145024.1
NM_144963.1,XM_145018.2,BC145001.1,AK145030.1
NM_144989.1,XM_030711.2
NM_145015.2
NM_145034.1

2 个答案:

答案 0 :(得分:5)

直接解析并直接写入Excel电子表格,而无需导入:

use Spreadsheet::WriteExcel;                                                    

my %hash;                                                                       

# Parse the data into a hash of arrayrefs                                       
push @{$hash{substr $_, 0, 2}} => $_ for <DATA>;                               

# Create spreadsheet                                                            
my $workbook = Spreadsheet::WriteExcel->new('perl.xls');                        
my $worksheet = $workbook->add_worksheet;                                       

# Loop through hashref keys                                                     
my @array = sort keys %hash;                                                    
for (0..@array-1) {                                                             

  # Create column based on arrayref                                             
  $worksheet->write_col(0, $_, $hash{$array[$_]});.                             
}                                                                               

# Close and save spreadsheet                                                    
$workbook->close;                                                               

答案 1 :(得分:4)

使用这样的并行数组是一个坏主意。实际上,每当您发现自己使用@array1@array2等名称时,请认识到这是个坏主意。而且,不,命名数组@NM@XM等不会让它变得更好。

我看到它的方式,你有一列数据,而你没有指定如何将该单列拆分为多列。 ...... 不,我的思维阅读能力不足。请发布所需的输出,不要让我们想象出来。

use strict; use warnings;
use List::AllUtils qw( each_arrayref);

my @fields = qw( NM XM BC AK );
my %data;

while ( <DATA> ) {
    chomp;
    if ( /^([A-Z]{2})_?[0-9]+\.[0-9]$/ ) {
        push @{ $data{$1} }, $_;
    }
}

print join(',', @fields), "\n";

my $it = each_arrayref @data{ @fields };

while ( my @values = $it->() ) {
    print join(',', map{ defined($_) ? $_ : '' } @values ), "\n";
}

__DATA__
NM_144736.3
NM_144963.1
XM_144975.2
BC144986.1
NM_144989.1
BC145001.1
XM_145018.2
NM_145015.2
XM_030711.2
AK145024.1
AK145030.1
NM_145034.1

输出:

NM,XM,BC,AK
NM_144736.3,XM_144975.2,BC144986.1,AK145024.1
NM_144963.1,XM_145018.2,BC145001.1,AK145030.1
NM_144989.1,XM_030711.2,,
NM_145015.2,,,
NM_145034.1,,,
相关问题