0

我有很多这样格式的数据

Amistad Academy District Amistad Academy    596 812 73.4
Andover School District  Andover            39  334 11.7
Ansonia School District  Ansonia High School    427 732 58.3
Ansonia School District  Ansonia Middle School  219 458 47.8
Ansonia School District  Mead School            431 642 67.1
Ansonia School District  Prendergast School 504 787 64

我需要做的是 grep 一堆学区,然后取最后一列,总结所有匹配的学区(例如所有 Ansonia),然后将该数字除以倒数第二列的总和。我可以毫不费力地将学区放入单独的文件中。那只是一个grep。然而,现在,我被困住了,认为在 excel 中做这件事可能更容易。我一直在玩 perl 中的解决方案,比如

  1 #!/opt/local/bin/perl
  2 use strict;
  3 use warnings;
  4 use ARGV::readonly;
  5 
  6 my @data;
  7 my @headers - split ',', <>;
  8 
  9 while (<>) {
 10   my @row = split;
 11   $data[$_] += $row[$_] for (0 .. $#row);
 12 }
 13 
 14 $" = "\t";
 15 print "@headers", "\n";
 16 print "@data";

但无法弄清楚进行加法和除法的语法。

谢谢。

4

2 回答 2

1

您正在对每一列求和。您只想将其中两个相加。否则,您实际上就在那里。

my $sum_last = 0;  # Use better name.
my $sum_penu = 0;  # Use better name.
while (<>) {
   chomp;
   my @row = split /\t/;
   next if $row[0] ne 'Ansonia School District';
   $sum_last += $row[-1];
   $sum_penu += $row[-2];
}

say $sum_last / $sum_penu;
于 2012-05-22T17:19:13.897 回答
0

下面的程序将从文件中挑选出值,并将每个学区的运行总数保存在一个散列中。读取所有数据后,将打印散列的内容。它适用于未过滤的文件 - 您不必将其 grep 到单独的源中。

我注意到您的数据似乎是制表符分隔的,并且使用它很重要,split /\t/这样包含空格字符的字段也不会被拆分。

您没有说明数据的含义,因此我无法使代码更具可读性。

如果您还有其他问题,请再次询问。

use strict;
use warnings;

open my $fh, '<', 'myfile' or die $!;

scalar <$fh>; # lose header record

my %data;

while (<$fh>) {
  my @fields = split /\t/;
  my $district = shift @fields;
  $data{$district}[0] += $fields[-2];
  $data{$district}[1] += $fields[-1];
}

for my $district (sort keys %data) {
  printf "%s - %f\n", $district, $data{$district}[1] / $data{$district}[0];
}

输出

Andover School District - 0.035030
Ansonia School District - 0.090569
于 2012-05-22T17:54:03.893 回答