我想创建一个散列,其中列标题为散列键,列值为Perl中的散列值。
例如,如果我的csv文件包含以下数据:
A,B,C,D,E
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15 ...
我想创建一个哈希,如下所示:
A=> 1,6,11
B=>2,7,12
c=>3,8,13 ...
因此,只需使用标题名称,我就可以使用该列值。 PERL有办法做到这一点吗?请帮帮我。
我能够使用以下脚本将所需的列值存储为数组
use strict;
use warnings;
open( IN, "sample.csv" ) or die("Unable to open file");
my $wanted_column = "A";
my @cells;
my @colvalues;
my $header = <IN>;
my @column_names = split( ",", $header );
my $extract_col = 0;
for my $header_line (@column_names) {
last if $header_line =~ m/$wanted_column/;
$extract_col++;
}
while ( my $row = <IN> ) {
last unless $row =~ /\S/;
chomp $row;
@cells = split( ",", $row );
push( @colvalues, $cells[$extract_col] );
}
my $sizeofarray = scalar @colvalues;
print "Size of the coulmn= $sizeofarray";
但是我想对我的所有专栏做这个。我猜数组的哈希将是最好的解决方案,但我不知道如何实现它。
答案 0 :(得分:2)
Text::CSV
是一个有用的辅助模块。
use strict;
use warnings;
use Text::CSV;
use Data::Dumper;
my %combined;
open( my $input, "<", "sample.csv" ) or die("Unable to open file");
my $csv = Text::CSV->new( { binary => 1 } );
my @headers = @{ $csv->getline($input) };
while ( my $row = $csv->getline($input) ) {
for my $header (@headers) {
push( @{ $combined{$header} }, shift(@$row) );
}
}
print Dumper \%combined;
由于您没有使用模块请求 - 可以使用split
,但您需要牢记这些限制。 CSV
格式允许嵌套在引号中的逗号。 split
不能很好地处理这个案子。
use strict;
use warnings;
use Data::Dumper;
my %combined;
open( my $input, "<", "sample.csv" ) or die("Unable to open file");
my $line = <$input>;
chomp ( $line );
my @headers = split( ',', $line );
while (<$input>) {
chomp;
my @row = split(',');
for my $header (@headers) {
push( @{ $combined{$header} }, shift(@row) );
}
}
print Dumper \%combined;
注意:这两个都会有效地忽略任何没有标题的额外列。 (并且会因重复的列名而感到困惑)。
答案 1 :(得分:1)
使用for
循环的另一种解决方案:
use strict;
use warnings;
my %data;
my @columns;
open (my $fh, "<", "file.csv") or die "Can't open the file : ";
while (<$fh>)
{
chomp;
my @list=split(',', $_);
for (my $i=0; $i<=$#list; $i++)
{
if ($.==1) # collect the columns, if its first line.
{
$columns[$i]=$list[$i];
}
else #collect the data, if its not the first line.
{
push @{$data{$columns[$i]}}, $list[$i];
}
}
}
foreach (@columns)
{
local $"="\,";
print "$_=>@{$data{$_}}\n";
}
输出将如下:
A=>1,6,11
B=>2,7,12
C=>3,8,13
D=>4,9,14
E=>5,10,15