perl将2个不同文件中的2个数组的结果一起添加

时间:2014-08-26 15:12:55

标签: arrays perl

我在2个csv文件之间运行一个报告,我想要检查的最后一个位是将2个数组的匹配元素(由唯一值和出现组成)添加到一起。但我无法解决如何为每个阵列中的每个匹配名称添加一起,以获得如下输出。

INPUT:

jon  22          
james  12         
ken    22            
jack    33         
jim     11         
harry    7
dave     9
grant    12
matt     74
malc     12

INPUT1:

jon  2    
james  1         
ken    8           
jack    5         
jim     1        
harry    51
dave     22

期望的输出:

jon  24       
james  13     
ken    30           
jack    38  
jim     12     
harry    58
dave     31
grant    12
matt     74
malc     12 

代码我这样做是为了从INPUT和INPUT1

创建oput
my %seen;
seek INPUT, 0, 0;
while (<INPUT>)

{
    chomp;
    my $line = $_;
    my @elements = split (",", $line);
    my $col_name = $elements[1];
    #print "    $col_name  \n" if ! 
    $seen{$col_name}++;
}

while ( my ( $col_name, $times_seen ) = each %seen ) {
    my $loc_total = $times_seen * $dd;
    print "\n";

    print "     $col_name \t\t :  = $loc_total";

    printf OUTPUT "%-34s = %15s\n", $col_name , " $loc_total ";

}
##############                          ###################

my %seen2;
seek INPUT1, 0, 0;
while (<INPUT1>)
{
    chomp;
    my $line = $_;
    my @elements1 = split (",", $line);
    my $col_name = $elements1[1];
    my $col_type = $elements1[5];

    $seen2{$col_name}++ if $col_type eq "YES";
}

while ( my ( $col_name, $times_seen2 ) = each %seen2 ) {
    my $loc_total = $times_seen2 ;

    print "\n    $col_name \t\t= $loc_total";
    printf OUTPUT "%-34s = %15s\n", $col_name , $times_seen2 ;
}

close INPUT;

3 个答案:

答案 0 :(得分:1)

不使用%see,而是将运行总计直接存储在哈希中:

#!/usr/bin/perl
use warnings;
use strict;

my %count;
for my $file ('INPUT', 'INPUT1') {
    open my $IN, '<', $file or die "$file: $!";
    while (<$IN>) {
        my ($name, $num) = split;
        $count{$name} += $num;
    }
}

for my $name (sort { $count{$b} <=> $count{$a} } keys %count) {
    print "$name\t$count{$name}\n";
}

答案 1 :(得分:0)

首先,我假设输入文件是实际的CSV文件 - 而您的示例只是以空格分隔。换句话说:

jon,22          
james,12         
ken,22            
jack,33         
jim,11         
harry,7
dave,9
grant,12
matt,74
malc,12

jon,2    
james,1         
ken,8           
jack,5         
jim,1        
harry,51
dave,22

ASSUMING 我是对的,那么你的while循环就可以解决这个问题,并进行了一些调整:

  1. @elements数组的第一个元素有索引0,而不是1.所以这里的“key”是$ elements [0],而“value”是$ elements [1]。所以你有类似的东西:

    my $ col_name = $ elements [0];

    我的$ col_value = $ elements [1];

  2. 添加值似乎更有用,而不是增加%,如下所示:

    $ seen {$ col_name} + = $ col_value;

  3. 在你的while循环中迭代INPUT1 ,在第一个循环中做同样的事情来提取数据;另外,不要使用%seen2;相反,只需添加到上面看到的%:

    我的$ col_name = $ elements1 [0];

    我的$ col_value = $ elements1 [1];

    $ seen {$ col_name} + = $ col_value;

  4. 您的总数将以%see的形式存储,因此您的最终while循环会略有修改:

  5. while(my($ col_name,$ times_seen2)=看到的每个%){#而不是%seen2

    如果你的两个处理循环是相同的(我看到它们可能不是),那么我建议将它们分解为一个公共子程序。但那是另一回事。

答案 2 :(得分:0)

以下内容可以很容易地适用于从命令行中获取文件名。

维护文件中密钥的顺序:

use strict;
use warnings;
use autodie;

my @names;
my %total;

local @ARGV = qw(INPUT INPUT1);
while (<>) {
    my ($name, $val) = split;
    push @names, $name if ! exists $total{$name};
    $total{$name} += $val;
}

for (@names) {
    print "$_ $total{$_}\n";
}