Perl帮助...读取文件...数学...写文件? Perl的新功能

时间:2011-02-22 20:35:40

标签: perl

我有一个这样的文件:

DATA_SET1
INFO1 INFO2 INFO3 = ### ### ###
INFO4 = ###
INFO5 = ###
INFO6 = ###
INFO7 = ###
INFO8 = ###
DATA_SET2
INFO1 INFO2 INFO3 = ### ### ###
INFO4 = ###
INFO5 = ###
INFO6 = ###
INFO7 = ###
INFO8 = ###
etc...

我需要对数字做一些统计。 EX:来自DATASET1,DATASET2等的INFO4号的平均值......然后我必须将平均值写入另一个文件:

STATISTICS:
INFO4 Average: ### 

我对PERL非常新。这可能很容易做到,我只是不知道从哪里开始。

谢谢你的帮助!

3 个答案:

答案 0 :(得分:2)

首先,您需要将文件放入数据结构中。如果您拥有的格式总是相同,那么这样的东西应该有效。

#!/usr/bin/env perl

use strict;
use warnings;

use Data::Dumper; # for printing the hash of results at the end

my $file = $ARGV[0]; # Specify the file as first command line argument
open my $fh, '<', $file;

my %data;
my $current_set = 'default';
while(my $line = <$fh>) {
  chomp $line;
  if ($line =~ /(DATA_SET\d+)/) {
    $current_set = $1;
  } elsif ($line =~ /=/) {

    my ($vars, $vals) = split(/\s*=\s*/, $line);

    my @vars = split(/\s/,$vars);
    my @vals = split(/\s/,$vals);

    die "length of variable declarations is not equal to length value declarations" 
      unless (@vars == @vals);

    while (@vars) {
      my $var = shift @vars;
      my $val = shift @vals;
      $data{$current_set}{$var} = $val;
    }
  }
}

print Dumper \%data;

#This assumes that each DATA_SET has an INFO4 term. 
#  N.B. It will assume a zero if not defined!
my @INFO4 = map { $data{$_}{'INFO4'} } keys %data;
die "Nothing to average" unless @INFO4;

my $sum;
foreach (@INFO4) {
  $sum += $_;
}
my $av = $sum / scalar @INFO4;

print "$av\n";

最后我只打印创建的数据结构,你需要在这里做功课来使用这个数据结构(编辑:在INFO4术语上增加了平均值)。 perldoc是一个很好的起点。另外,如果你需要一些高性能的数学运算,我会看一下Perl Data Language (PDL)在Perl中实现快速数组数学(类似Matlab)数值语言。

祝你好运。

答案 1 :(得分:1)

如果你知道不止一个langiage,我会从Learning PerlProgramming PerlPerl Cookbook开始

答案 2 :(得分:1)

如果您只是计算INFO 4值的平均值,您可能只需使用正则表达式来识别和拆分这些值。这是一个粗略的脚本示例,您可以使用它来开始(这些不一定是最佳实践,但我试图说明发生了什么)。它读取一个数据文件,并在它是Info 4值时添加到平均值。 (我使用substring假设数据输入中没有错误,但同样,这只是一个粗略的答案,适用于您的示例案例)。您可能还需要考虑使用sprintf来根据需要舍入您的值(它当前将充当浮点数)。希望这会有所帮助。

open (IN, "file.txt") or die "Unable to open input file.\n";
while ($line = ){
    chomp($line);
    if ($line =~ m/INFO4/i){
        $average += int(substr($line, 8,length $line));
        $count++;
    }
}
close (IN);
$average = ($average/$count) if $count > 0;

open (OUT, ">output.txt") or die "Unable to open output file.\n";
print OUT "INF04 Average: $average\n";
close(OUT);