• ベストアンサー

各クラスの平均身長・体重を計算するスクリプト

標記の件で、至急困っています。 perl でも awk でも良いので次のようなスクリプトを教えてください。 ぜひお願いします!!Linux上で作業をやることになってます。 1年生の各クラスの生徒のデータは、クラスごとに 1/class1 1/class2 1/class3 1/class4 1/class5 のように学年を表す数字のディレクトリに データファイルが入っています。 2年生のデータも同様で、 2/class1 2/class2 ・・・ 2/class4 2/class5 のような感じです。 各学年5クラスで、全部で6学年あります。 各クラス、だいたい生徒が40人くらいで、 データファイル class* には、身長、体重が 山田 131 23 高橋 135 24 ・・・ のように記録されています。 以上のデータを各クラスごとに平均を計算して、 1-nen 1-kumi 125.3 20.5 1-nen 2-kumi 120.2 18.9 ... 6-nen 5-kumi 140.6 44.9 のような出力を得るにはどうすればよいでしょうか? よろしくおねがいいたします!

質問者が選んだベストアンサー

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

> $path =~ m|(\d)/class(\d)|; について 変数 =~ m/パターン/; で変数とパターンのマッチングを行います。 m//の替わりにm||を使っているのは、 パターンの中で / を使っているためです。 m/パターン1/パターン2/ のようには書けないので m/パターン1\/パターン2/ のようにする必要があるんですが、紛らわしいです。 そういう場合、m//をm||で代替できます 1/class2 と (\d)/class(\d) をマッチングすると (\d)が数字の部分とマッチします。 マッチしたものは、それぞれ $1,$2に順番に入ります つまり例の場合 $1=1,$2=2 になります

white-tiger
質問者

補足

> 1/class2 と (\d)/class(\d) をマッチングすると > (\d)が数字の部分とマッチします。 > マッチしたものは、それぞれ > $1,$2に順番に入ります 衝撃を受けました。便利ですね。 ありがとうございます!

その他の回答 (3)

  • Hasty
  • ベストアンサー率73% (19/26)
回答No.4

> /(\d)/g > の\dとgの意味 ここでは「1/class1」などの文字列が入っているはずの特殊変数$_から、正規表現で年と組を取り出しています。 「\d」は正規表現の数字を表すメタ文字で、「g」はマッチするものを全部取り出すというオプションです。 > or die "$!: $_"; > "$!: $_" の役割 「$!」にはopenが失敗した理由(エラーメッセージ)が入っていて、「$_」にはファイル名が入っています。つまり、openが失敗した理由と、開けなかったファイル名を表示するようにしています。 or die "ファイルが開けませんでした"; のように書いてもいいんですが、これだと何で開けなかったのか、どのファイルが開けなかったのか、などが分からないのでこの様にしてます。

white-tiger
質問者

補足

一気に成長できました。 ありがとうございます!

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

sub ave ($){ my $path = shift; my (@field, $sumH, $sumW, $count); unless(open(F, $path)){ warn "Can't open $path\n"; return ; } while(<F>){ @field = split; $sumH += $field[1]; $sumW += $field[2]; $count++; } close(F); $path =~ m|(\d)/class(\d)|; printf("%d-nen%d-kumi %4.1f %3.1f\n",$1,$2,$sumH/$count,$sumW/$count); } for($nen=1;$nen<=6;$nen++){ for($kumi=1;$kumi<=5;$kumi++){ ave("./$nen/class$kumi"); } }

white-tiger
質問者

補足

ありがとうございます! > $path =~ m|(\d)/class(\d)|; について教えていただけないでしょうか? 特に ~ と | と \d の役割が・・

  • Hasty
  • ベストアンサー率73% (19/26)
回答No.1

こんな感じ。 foreach (sort glob("?/class?")) { my ($nen, $kumi) = /(\d)/g; my ($height, $weight); open FH, $_ or die "$!: $_"; while (<FH>) { my @part = split /\s/; $height += $part[1]; $weight += $part[2]; } printf "%d-nen %d-kumi %.1f %.1f\n", $nen, $kumi, $height/$., $weight/$.; close FH; } 分からないとこがあれば補足下さい。

white-tiger
質問者

補足

ありがとうございます! このコードを参考にネットでいろいろ勉強してみましたが、 ・ /(\d)/g の\dとgの意味と、 ・or die "$!: $_"; "$!: $_" の役割 を教えていただけないでしょうか?

関連するQ&A