满足条件时,将多个值一起添加?

时间:2018-02-28 15:56:32

标签: perl csv aggregate

我的思绪似乎在今天缺少一些螺丝。我有一个令我感到困惑的问题,但公平地说,我是Perl脚本的新手。

我正在打开一个csv文件,需要在一列中查找重复值,如果此列中有重复项,我需要将每个副本的另一列中的所有值添加到一起并将其打印在新行中一个新文件。

open(my $feed, '<', $rawFile) or die "Could not locate '$rawFile'\n";
open(OUTPUT, '>', $newFile) or die "Could not locate '$newFile'\n";
while(my $line = <$feed>) {
    chomp $line;

    my @columns = split /,/, $line;
    $Address= $columns[1];
    $forSale= $columns[3];

}

我了解如何打开文件并逐行阅读。我知道如何将结果打印到新文件。我遇到的问题是构建逻辑说,&#34;对于此摘录中的每个地址重复,添加所有的forSale并在新文件中打印地址添加了forSale的值。我希望这是有道理的。鼓励任何协助。

2 个答案:

答案 0 :(得分:3)

此工作所需的工具是hash

这将允许您通过地址“键入”事物:

my %sum_of;

while(my $line = <$feed>) {
    chomp $line;

    my @columns = split /,/, $line;
    $Address= $columns[1];
    $forSale= $columns[3];

    $sum_of{$Address} += $forSale; 

}

foreach my $address ( sort keys %sum_of ) {
    print "$address => $sum_of{$address}\n";
}

答案 1 :(得分:1)

您好Chris Simmons

我想对Sobrique为您提供的完美答案添加一些小修改。

您可以按照您的方式打开文件,但也可以在命令行上打开多个文件,例如test.pl sample1.csv sample2.csv,您可以在此处阅读eof

我还会选择检查文件是否包含逗号字符(,)否则在终端上打印该行无法解析。

在分割数组中的所有值之后的下一步,我将修剪字符串以查找前导和尾随的空白区域。

已经说过所有看到解决方案了:

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my %hash;
while (<>) {
    chomp;
    if (index($_, ',') != -1) {
    my @fields = split(/,/);
    # remove leading and trailing white space
    s{^\s+|\s+$}{}g foreach @fields;
    $hash{$fields[0]} += $fields[3];
    }
    else {
    warn "Line could not be parsed: $_\n";
    }
} continue {
    close ARGV if eof;
}
print Dumper \%hash;

__END__

$ perl test.pl sample.csv
$VAR1 = {
          '123 6th St.' => 3,
          '71 Pilgrim Avenue' => 5
        };

__DATA__

123 6th St., Melbourne, FL 32904, 2
71 Pilgrim Avenue, Chevy Chase, MD 20815, 5
123 6th St., Melbourne, CT 06074, 1

由于您未向我们提供输入数据样本,因此我创建了自己的输入数据。

另一种可能的方法是将模块Text::CSV用作ikegami提议。我之前提到的具有相同检查的代码示例,请参见下文:

#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;
use Data::Dumper;

my $csv = Text::CSV->new({ sep_char => ',' });

my %hash;
while (<>) {
    chomp;
    if ($csv->parse($_)) {
    my @fields = $csv->fields();
    # remove leading and trailing white space
    s{^\s+|\s+$}{}g foreach @fields;
    $hash{$fields[0]} += $fields[3];
    } else {
    warn "Line could not be parsed: $_\n";
    }
} continue {
    close ARGV if eof;
}
print Dumper \%hash;

__END__

$ perl test.pl sample.csv
$VAR1 = {
          '123 6th St.' => 3,
          '71 Pilgrim Avenue' => 5
        };

__DATA__

123 6th St., Melbourne, FL 32904, 2
71 Pilgrim Avenue, Chevy Chase, MD 20815, 5
123 6th St., Melbourne, CT 06074, 1

希望这有帮助。

BR / Thanos