在perl中读取CSV文件中的部分行

时间:2014-02-04 10:15:07

标签: perl

我正在尝试读取具有如下数据的csv文件:

++++++++++++++++++++++++++++

My1,10,20,30,40,50,60,70

My2,10,20,30,40,50,60

My3,10,20,30,40,50,60,70,80

++++++++++++++++++++++++++++

现在我想在@names中存储My,My1 ....并将每行中的数字存储到@numbers

直到现在我已经制作了这段代码

  use strict;
  use warnings;
  use Text::CSV;

  my $file = "result.csv";
  my @names = undef;
  my @numbers = undef;
  open my $fh, "<", $file or die "$file: $!";

  my $csv = Text::CSV->new ({
      binary    => 1,
      auto_diag => 1,
      });
    shift(@names);
    shift(@numbers);
  while (my $row = $csv->getline ($fh)) {
    push(@names,$row->[0]);
    push(@numbers,$row->[1...5]);
      }
  close $fh;

for my $i ( 0 .. $#names ) {
    print "names:$names[$i] \tNumbers:$numbers[$i] \n";
}

但是这段代码不起作用,只是当我在打印时使用@numbers然后打印所有名称前面的所有数字

2 个答案:

答案 0 :(得分:1)

也许我不明白这个问题,但这里有可能的解决方案:

读:

...
my @names = ();
my @numbers = ();

open CSVFILE, 'result.csv';
my $j = 0;
while (my $line = <CSVFILE>) {
  chomp;
  my @csv_line = split(/\s?,\s?/, $line);
  push @names, $csv_line[0]; #or $names[$j] = $csv_line[0];
  for (my $i = 1; $i <= $#csv_line; $i++) {
    $numbers[$j][$i] = $csv_line[$i]; # $i-th number, for the $j-name
  }
  $j++;
}
close(CSVFILE);

写作:

...
my $name;
my @numbers;
my $new_line = join(',', ($name, @numbers));
open CSVFILE, '>>result.csv';
print CSVFILE "$new_line\n";
close CSVFILE;

印刷:

...
my $M = $names;
for (my $i = 0; $i < $M; $i++) {
  print $names[$i] . ":\n ";
  my $N = $numbers[$i];
  for (my $k = 0; $k < $N; $k++) {
    print $numbers[$i][$k] . " ";
  }
  print "\n";
}
...

打印:

My1:
 10 20 30 40 50 60 70 
My2:
 10 20 30 40 50 60 
My3:
 10 20 30 40 50 60 70 80 

答案 1 :(得分:1)

如果您考虑使用最合适的数据结构,这样的问题通常更容易解决。将链接数据存储在两个不同的变量(例如@names@numbers)中并不是一个好主意。

我已将数据存储在哈希中。键是您的名字,值是对存储您的号码的数组的引用。

(哦,为了简化示例,我已经切换到将数据存储在源文件中。)

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

use Text::CSV;

my %data;
my $csv = Text::CSV->new ({
  binary    => 1,
  auto_diag => 1,
});

while (my $row = $csv->getline(\*DATA)) {
  # First element in @$row is the name, which we use as the key.
  # Rest of @$row contains the numbers.
  $data{shift @$row} = $row;
}

foreach (sort keys %data) {
  say "$_: @{$data{$_}}";
}

__END__
My1,10,20,30,40,50,60,70
My2,10,20,30,40,50,60
My3,10,20,30,40,50,60,70,80