解析CSV文件和散列

时间:2013-05-18 19:52:26

标签: perl parsing csv hash

我正在尝试解析CSV文件以读取所有其他邮政编码。我正在尝试创建一个散列,其中每个键都是一个邮政编码,值是它在文件中出现的数字。然后我想打印出内容为邮政编码 - 数字。这是我到目前为止的Perl脚本。

use strict;
use warnings;

my %hash = qw (
     zipcode count
);

my $file = $ARGV[0] or die "Need CSV file on command line \n";

open(my $data, '<', $file) or die "Could not open '$file $!\n";
while (my $line = <$data>) {
   chomp $line;
   my @fields = split "," , $line;
   if (exists($hash{$fields[2]})) {
        $hash{$fields[1]}++;
   }else {
        $hash{$fields[1]} = 1;
   }
}

my $key;
my $value;
while (($key, $value) = each(%hash)) {
  print "$key - $value\n";
}

exit;

2 个答案:

答案 0 :(得分:5)

您没有说明您的邮政编码所在的列,但您使用的是第三个字段来检查现有的哈希元素,然后使用第二个字段来增加它。

无需检查哈希元素是否已存在:Perl将很乐意创建一个不存在的哈希元素,并在您第一次访问它时将其递增为1.

也无需显式打开作为命令行参数传递的任何文件:如果您使用<>运算符而没有文件句柄,Perl将打开它们并读取它们。

您自己的程序的重新编写可能会起作用。它假定邮政编码位于CSV的第二列。如果它在其他任何地方,只需适当地更改++$hash{$fields[1]}

use strict;
use warnings;

@ARGV or die "Need CSV file on command line \n";

my %counts;

while (my $line = <>) {
   chomp $line;
   my @fields = split /,/, $line;
   ++$counts{$fields[1]};
}

while (my ($key, $value) = each %counts) {
  print "$key - $value\n";
}

答案 1 :(得分:2)

很抱歉,如果这是偏离主题的,但如果您使用的是使用标准Unix文本处理工具的系统,则可以使用此命令计算字段#2中每个值的出现次数,而不需要写任何代码。

cut -d, -f2 filename.csv | sort | uniq -c

将生成类似于此输出的内容,其中首先列出计数,然后列出第二个zipcode:

12 12345
2 56789
34 78912
1 90210