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

问题描述 投票:0回答:2

我的思绪今天似乎缺少一些螺丝。我有一个令我感到困惑的问题,但公平地说,我是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];

}

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

perl csv aggregate
2个回答
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
投票

你好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

© www.soinside.com 2019 - 2024. All rights reserved.