グッドデザイン賞を受賞したウォーターサーバー >>

外部ファイル(ここではCSVファイル)内の列ごとの数値を合計し、結果をコマンドに表示したいです。

数値を合計するためsum関数を用いることは分かったのですが、各列ごとの出力・数値の合計はどのようにすればいいのですか。

合計計算のイメージはこんな感じです。

CSVファイル内

1 , 25
2 , 50
3 , 75
 ・
 ・
 ・

プログラムで外部ファイルを読み込み、各列ごとの和を計算し、

Σx=1+2+3+・・・
Σy=25+50+75+・・・

コマンド(Cygwinを使用しています)上で、

x = (数値) , y = (数値)

と表示することです。

A 回答 (2件)

手元にperlがないので実際に動かしてないですがこんなかんじですかねぇ



open (FH, $ARGV[0]); #$ARGV[0]はファイル名
while (<FH>) {
@line = split /,/;
$x += $line[0];
$y += $line[1];
}
close (FH);
print "x=$x y=$y";
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

列ごとの数値を合計する方法が分からなかったのですが、記述して頂いた、
@line = split /,/;
$x += $line[0];
$y += $line[1];

の部分を参考にすると出来ました。

ありがとうございます。

お礼日時:2012/10/16 13:58

「sum関数」? 何それ.



1行に 1個だけだったら, 和を計算することはできますか?
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q複数ファイルの読み込みについて

perl初心者です。

あるディレクトリから拡張子がdataであるファイルを全て読み込みたいのですが、方法がわかりません。
cshで書くと
foreach arg (*.data)
コマンド $arg

のようになりますが、perlだと
foreach $arg (@arg){
コマンド $arg

となりますよね?
引数がリストなのでよくわかりません。
そもそもperlではできないのでしょうか?


それともう一点ですが、ファイルオープンするときに
foreachループの中で
open(FILE, "$arg");
とすることは可能ですか?
上の質問と組み合わせて全てのファイルを開いて作業を行いたいので。

説明が下手ですいません。補足しますのでよろしくお願いします。

Aベストアンサー

while(<*.data>)
{
## $_には、*.DATAなファイル名が格納されている。
open(F,"$_"); ##openする。
while(<F>)
{
##読み出された内容が$_に格納されている。
print $_; ##出力してみる。
}
}

というのが最短コーディングです。

QPerlで特定行から特定行までを抜き出したい

皆さんのお知恵をお貸し頂ければ幸いです。

Perlで以下のようなことをしたいと考えています。
例えば、次のようなテキストファイルがあったとします。

example.log
==================================
aaaa
hogehoge
test
okok
perl
script
==================================

上記ファイルを読み込んで、「hogehoge」から「perl」の間に挟まれた行だけ抜き出したいのです。
イメージとしては、読み込んだファイルを配列に入れて、一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

このような場合、どういう風にすればいいのでしょうか?
恐れ入りますが、ご教授頂ければ幸いです。

それでは、どうぞよろしくお願い致します。

Aベストアンサー

> 一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

それでいいと思いますよ?これをそのままコード化すると、こんな感じでしょうか。(No.1さんのとはちょっと結果が違います。)

open FH, "example.log" or die $!;
$flag = 0;
while ($data = <FH>) {
  chomp $data;
  if  ($data eq "hogehoge") { $flag = 1 }
  elsif ($data eq "perl")    { $flag = 0 }
  elsif ($flag) { print "$data\n" }
}
close FH;

で、もっと略したいPerlな人だとこんな感じ。Perl独特の記法がふんだんに使われているので、勉強するには不向きかもしれませんが^^;

open FH, "example.log" or die $!;
while (<FH>) {
  print if /^hogehoge$/ .. /^perl$/ and !/^(?:hogehoge|perl)$/;
}
close FH;

※インデントに全角空白を使っているので、コピーする場合はタブなどに置換して下さい。

> 一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

それでいいと思いますよ?これをそのままコード化すると、こんな感じでしょうか。(No.1さんのとはちょっと結果が違います。)

open FH, "example.log" or die $!;
$flag = 0;
while ($data = <FH>) {
  chomp $data;
  if  ($data eq "hogehoge") { $flag = 1 }
  elsif ($data eq "perl")    { $fl...続きを読む

QPerlで行頭にある文字が含まれている行を全部削除して詰めたい

perl初心者です。以下のようにデータがならんでいる時、
test111 aaaaaaaaabbbbbbbbcccccc
test112 aaaaccccabbbbbbbbcccccc
test113 aaaaccaaabbbbbbbbcccccc
test114 acccaaaaabbbbbbbbcccccc

test111 aacaaaaaabbbbbbbbcccccc
test112 accaaaaaabbbbbbbbcccccc
test113 aaacccaaabbbbbbbbcccccc
test114 aaaaaccaabbbbbbbbcccccc

test112の行だけ削除して、さらにそこを詰めたい時のスクリプトを作成しています。

途中からわかりません。
行を削除する関数が調べても見つからないのです。

#!/usr/bin/perl ;
open(IN, "test.doc") or die ;

open(OUT, ">testout.doc");

while(<IN>) {
chomp ;
if (/(\S+)/) {

$name = $1 ;

if ($name =~ /^test112(\S+)/) {
#ここでマッチさせて、一気に行を削除して、しかも行を詰めたいのですが

;

}
print OUT " \n" ;
}
}
close (IN) ;
close (OUT) ;

大変困っております。宜しくお願いします。

perl初心者です。以下のようにデータがならんでいる時、
test111 aaaaaaaaabbbbbbbbcccccc
test112 aaaaccccabbbbbbbbcccccc
test113 aaaaccaaabbbbbbbbcccccc
test114 acccaaaaabbbbbbbbcccccc

test111 aacaaaaaabbbbbbbbcccccc
test112 accaaaaaabbbbbbbbcccccc
test113 aaacccaaabbbbbbbbcccccc
test114 aaaaaccaabbbbbbbbcccccc

test112の行だけ削除して、さらにそこを詰めたい時のスクリプトを作成しています。

途中からわかりません。
行を削除する関数が調べても見つからないのです。

...続きを読む

Aベストアンサー

一致しなかったときのみ出力するということで、

while(<IN>){
unless(/^test112/){
print OUT;
}
}

更に簡単に書くと、
while(<IN>){
print OUT unless(/^test112/);
}
となります。

削除にこだわるなら、
while(<IN>){
s/^test112\s.+//;
print OUT;
}
あたりでしょうか。

もしくは、明示的に削除したいなら、
while(<IN>){
if(/^test112\s.+/){
$_ = "";
}
print OUT;
}
というふうに、カラの文字列を代入してやるのも、値を削除するときの常套手段ですね。

QCSV形式での集計

PHPでクイズのプログラムを作ったのですが、
CSVデータの件数が多いので処理に時間がかかり、
回答の集計で困ってます。

具体的に、
PHPクイズの回答をCSV形式でanswer.txtに記録させます。
記録の内容は、
問題1の回答番号、問題2の回答番号、問題3の回答番号、
というように記録させます。
このとき、1万件くらいの回答データが入ったanswer.txtから、
問題1で回答番号を1で答えた人の数、2で答えた人の数というように、
データの集計をしたいのですが、
効率の良い集計方法を教えていただければありがたいです。
自分が考えたのは、
1.file文で全行一括読み込みしてから
2.for文でデータを検証(総データ数分だけ繰り返す)
3.回答番号が一致したら、flagに+1をする
4.flagの数が集計結果となり、これを出力する
というルーチンです。
1万件くらいになると、あまり速くないです。
ちなみに、このルーチンで処理できるデータ件数って、
どのくらいが限度となるんでしょうか。

文章が稚拙で、長くなってしまい、すみません。
よろしくご指導、お願いします。

PHPでクイズのプログラムを作ったのですが、
CSVデータの件数が多いので処理に時間がかかり、
回答の集計で困ってます。

具体的に、
PHPクイズの回答をCSV形式でanswer.txtに記録させます。
記録の内容は、
問題1の回答番号、問題2の回答番号、問題3の回答番号、
というように記録させます。
このとき、1万件くらいの回答データが入ったanswer.txtから、
問題1で回答番号を1で答えた人の数、2で答えた人の数というように、
データの集計をしたいのですが、
効率の良い集計方法を教えていただければあ...続きを読む

Aベストアンサー

予め集計結果のファイルや途中結果を別にどっかへ置いておけばいいんじゃないですかね?
回答時にanswer.txtへ保存するのと同じでtotal.txtを作っちゃうとか。
バックグラウンド処理でたまに集計させておくとか。

データベースを使っても同じことが言えますが、予め集計しておいた方が早くなると思います。

>ちなみに、このルーチンで処理できるデータ件数って、
>どのくらいが限度となるんでしょうか。

遅いと思ったときはすでに限度だと思います。
HTMLを表示する時に3秒待たされると遅いって思うらしいですよ。

Qperlでawkのようなことはできるでしょうか?

perlなど初心者です。
awkでレコードのフィールドを$1、$2などと参照できるのが便利だなと感じているのですが、perlでもコマンドラインで同じ事をするにはどうすればよいでしょうか?

Aベストアンサー

コマンドラインオプション -a (と-F)を使います。

perldoc perlrun
すると細かい説明がわかります。
-a
turns on autosplit mode when used with a -n or -p. An implicit
split command to the @F array is done as the first thing inside the
implicit while loop produced by the -n or -p.

perl -ane 'print pop(@F), "\n";'

is equivalent to

while (<>) {
@F = split(' ');
print pop(@F), "\n";
}

An alternate delimiter may be specified using -F.

@F という配列に入力行を分割して格納します。
awk でいうところの print $1, $2 は
print $F[0], $F[1], "\n";
になります。
配列が0オリジンになることに注意してください。
awkでの$0は、この場合は $_ という変数に入っている値になります。

コマンドラインオプション -a (と-F)を使います。

perldoc perlrun
すると細かい説明がわかります。
-a
turns on autosplit mode when used with a -n or -p. An implicit
split command to the @F array is done as the first thing inside the
implicit while loop produced by the -n or -p.

perl -ane 'print pop(@F), "\n";'

is equivalent to

while (<>) {
@F = split(' ');
print pop(@F), "\n"...続きを読む

QPerlでcsvファイルを読み込んで計算する方法(初心者です)

csvファイルに以下のようなデータが入っています。
ID,X座標,Y座標
0,1.22,3.42
1,3.24,4.52
2,5.34,7.87
(こういうのがID1000までずっと続きます)

このデータから一行ずつ,Y座標-X座標を計算させて出力したいです。
とても困っているので解答お願いします。

Aベストアンサー

まさか一行ずつ読み取るのもどうやるかわからないということはないですよね。

> 0,1.22,3.42

これが $line という変数に入っているとして、
($id, $x, $y) = split q{,}, $line;
とすれば、
0 が $idに
1.22が$xに
3.42が$yに入ります。
あとは煮るなり焼くなりご自由に。

@fileds = split q{,}, $line;

のように配列変数で受けてもOKです。

ファイルにヘッダ行があるのなら適当に見分けてください。


人気Q&Aランキング