0

次のようなデータを含む file.txt があります。

word = blabla
a = 1
b = 2
c = 3
word = blabla_b
a = 11
b = 22
c = 33

(基本的に、このファイルは、このファイルに「a」に含まれる数字を書き込むJavaコードによって作成され、その後、特定のループで「b」と「c」、明らかにa、b、c 1、2、3になりますは単なる例です。私は別の名前と別の番号を持っています :-) )

私がする必要があるのは:

  1. CMD から与えられたファイルから読み取る
  2. それをCSVファイル(Excelで開く)に書き込み、すべての列の下部(数値ではないため「単語」を除く)に書き込み、平均を取得します:(Excelファイルで平均を計算する方法は知っていますが、単独で実行するスクリプト)

最終的には次のようになります。

ここに画像の説明を入力

私はそれが機能する一般的ではないことをしましたが、非常に愚かであり、もっとエレガントな方法があると確信しています!!!

my $in_file = shift;  
my $fileName = "CSV_file";
open $out_file, ">$fileName.csv" or die "can't open $fileName: $!";
my @fields = ("word","a","b","c");
foreach (@fields)
{   
    #first write down the line of the headlines per each column
    print $out_file "$_,";  
}
print $out_file "\n";
open STATS, "<$in_file" or die "Error opening file \$in_file";
local($counter) = 0;
#creating avg and sum variables for each column - not clever once i'll have much more columns!!!!!!!!!
my $avgA = 0 , $avgB = 0 ,$avgC = 0;
my $sumA = 0 , $sumB = 0 ,$sumC = 0;

my $numOfRows = 0;
while (<STATS>)
{
    chop;
    ($name, $number) = split("=");  
    print $out_file "$number";

    if ($counter == $#fields) #end of row
    {
        print $out_file "\n";
        $sumC += $number;
        $counter = 0;
        $numOfRows++;
    }
    else
    {
        print $out_file ",";
        $counter++;
    }
    #adding to the Sum of each column (in order for future Avg calc)
    if ($counter == 2)
    {
        $sumA += $number;
    }
    elsif ($counter == 3)
    {
        $sumB += $number;
    }
}
$avgA = $sumA/$numOfRows;
$avgB = $sumB/$numOfRows;
$avgC = $sumC/$numOfRows;


print $out_file "AVG:,$avgA ,$avgB,$avgC \n";
close (FILE);
4

2 に答える 2

1

データ構造が必要であることはわかっていますが、どのリストかわかりません。ハッシュまたは配列。– user1584314

個人的には、メイン データに配列のハッシュを使用し、いくつかの補助配列を使用して単語のリストを追跡し (順序を維持するため)、各列の値の合計を記録します。次のようなもの:

#!/usr/bin/env perl    

use warnings;
use strict;
use 5.010;

my @word;
my %raw_values;
my $record_number = -1;

while (my $line = <DATA>) {
  my ($col, $val) = $line =~ /(\w+)\s*=\s*(.*)/;
  if ($col eq 'word') {
    $record_number++;
    $word[$record_number] = $val;
  } else {
    $raw_values{$col}[$record_number] = $val;
  }
}

say 'word,', join(',', sort keys %raw_values);

for my $rec (0 .. $#word) {
  my @row = ($word[$rec]);
  for my $col (sort keys %raw_values) {
    push @row, ($raw_values{$col}[$rec] || '---');
  }
  say join ',', @row;
}

my @column_sum;
for my $col (sort keys %raw_values) { 
  my $sum = 0;
  for my $val (@{$raw_values{$col}}) {
    $sum += $val if defined $val && $val =~ /^\d+$/;
  }
  push @column_sum, $sum;
} 

say 'AVG:', join(',', map { $_ / scalar @word } @column_sum);

__DATA__
word = blabla
a = 1
b = 2
c = 3
word = blabla_b
a = 11
b = 22
c = 33
word=blabla_c
a=111
c=333
word=xyzzy
a=42
b=42
c=42

出力:

word,a,b,c
blabla,1,2,3
blabla_b,11,22,33
blabla_c,111,---,333
xyzzy,42,42,42
AVG:41.25,16.5,102.75

編集:平均計算を修正しましたが、正直なところ、(自分で修正したバージョンを書いた後)それを見たので@column_sum、ハッシュに変換して平均を計算するためのChris Charleyのソリューションが、自分のソリューションよりも優れていると言わざるを得ません正しく%raw_values計算するために余分な時間をループします。配列として見ることに夢中になりすぎて、それをハッシュに変更することを検討@column_sumできなかったに違いないと思います。@column_sum

于 2013-05-28T14:28:16.550 に答える