dポイントプレゼントキャンペーン実施中!

Perl初心者ですがよろしくお願いします。

テキストファイルのデータを読み込んで簡単な計算がしたいのですが、うまくいきません。

data.txt
-----------------------------------
年月    固定電話  携帯電話
18年3月  10,000   15,000
18年2月  12,000   14,000
18年1月  11,000   13,000
17年12月  9,000   15,000
17年11月  9,500   14,000
#(同様に続く)
-----------------------------------

特定の月(例えば17年12月)から過去1年分の固定電話・携帯電話の個別合計とその総計。また、月ごとの合計を出したいのですが、どのようにすればよいでしょうか?ご教授願います。m(_ _)m

A 回答 (4件)

問題解決済みと思いますが・・・



入力画面から年月を入れて、エクセルで計算結果を表示するプログラムを書いてみました。

#2さんの回答を参考に全角スペースのまま処理できるようになっています。

Windows でしか動きません・・・

参考URL:http://perllearner.web.fc2.com/denwa.htm
    • good
    • 0
この回答へのお礼

わざわざ大変な作業をしていただき、なんと言っていいのか・・とにかく感謝・感謝です。エクセルと連動させることも後々勉強しようと思っていたので大変参考になります。どうもありがとうございました。
m(_ _)m

お礼日時:2006/04/19 14:06

#2>#クックブック 2.16(P103)とは何でしょう?


オライリー社から出版されている
「Perlクックブック 第2版 VOLUME 1」
http://www.oreilly.co.jp/books/4873112028/
の103ページレシピ2.16を引用・使用しているということです。
(この本は、実用的なPerl コードの豊富なサンプルがあり、私にとってはバイブル的な本です。もし良ければ買ってあげて下さい。)
本の中のサンプルコードは、
原書のサイトである
http://www.oreilly.com/catalog/perlckbk2/
のExsample からプログラムのソースをダウンロードすることができます。
(本に載っている全てのコードではありません、断片的なものではなく、完成したプログラムのリストです。<全部チェックしているわけではないので断言はできませんが)
本の末尾に、通常の本ならあるように
「本書の一部あるいは全部について承諾を得ずに複写、複製を禁ず」(要約)
とありますが、
オライリー社の
「O'Reilly Policy on Re-Use of Code Examples from Books」
「本のサンプルコードの再利用に関するオライリーのポリシー」(私訳)
http://www.oreilly.com/pub/a/oreilly/ask_tim/200 …
によると、
「サンプルコードの再配布を承諾無しにしても良い」
(チェックすべきいくつかの項目が挙げられています、要点はオライリーの利益を損なわない(競合しない)ということです。個人的な使用や非営利で使われる)
とありますので、(私の英語力が低いために勘違いしていたら誰か教えて下さい)
こうした(非営利の)Web上でコードを再配布することは問題ないと思います。(ここでいう非営利とは、コードを得るために料金が発生しないというような意味であると思っています)
再配布することが認められているとしても、著作権が放棄されているわけではないので、このような場合には出典などを明記する必要があります。(もっとちゃんとした帰属を明示する必要があるかもしれませんが、クックブックと言えばわかると思っていました。次回から気をつけます)
    • good
    • 0
この回答へのお礼

無知な私に付き合っていただきありがとうございます。有名な書籍なのですね。HPを確認しました。是非購入しようと思います。ご親切にどうもありがとうございました。
m(_ _)m

お礼日時:2006/04/19 14:09

use encoding "cp932";



$order = "17年12月";#指定年月

($year, $month) = ($order =~ /(\d+)[^\d]+(\d+)/);
$year--;
if($month < 12){
$month++;
} else {
$month=1;
$year++;
}
$lastorder = "${year}年${month}月";

open(IN, "<:encoding(shiftjis)", "data.txt");
<IN>; #項目行読み飛ばし
while(<IN>){
($date, $homephon, $portable) = split(/[  ]+/);
if($date =~ /$order/ .. /$lastorder/){
$homephon =~ s/,//g;
$portable =~ s/,//g;
$sum{'固定電話計'} += $homephon;
$sum{'携帯電話計'} += $portable;
$sum{$date} = $homephon + $portable;
}
}
close(IN);
printf("%sから過去12ヶ月\n", $order);
printf("   総計:%10s\n", commify($sum{'固定電話計'}+$sum{'携帯電話計'}));
printf("固定電話計:%10s\n", commify($sum{'固定電話計'}));
printf("携帯電話計:%10s\n", commify($sum{'携帯電話計'}));
do{
$date = "${year}年${month}月";
printf(" %2d年%2d月:%10s\n", $year, $month, commify($sum{$date}));
if($month < 12){
$month++;
} else {
$month = 1;
$year++;
}
}until($date eq $order);

sub commify { #クックブック 2.16(P103)
my $text = reverse $_[0];
$text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g;
return scalar reverse $text;
}
    • good
    • 0
この回答へのお礼

返事が遅くなりまして申し訳ございません。
早速やってみます。
#クックブック 2.16(P103)とは何でしょう?

お礼日時:2006/04/19 09:12

# こんなんどうでしょう(長くてすみません)。


# 全角スペースでの split がわからなかったので、データはタブ区切りにしています。
# 余計なお世話かもですが、年は西暦にした方が長く使えるかと・・・


my $year = 17; my $month = 12;
# コマンドプロンプトから perl xxx.pl 17 12 などとして年月の値を入力するときは my $year=$ARGV[0]; my $month =$ARGV[1];

my $last_year = $year-1;
my $last_month = $month+1;

if ($last_month ==13){
$last_month = 1;
$last_year = $year;
}

my $mon1 = "$year年$month月";
my $mon2 = "$last_year年$last_month月";
my @one_year_data;

open DATAIN, "< data.txt";

while(<DATAIN>){
push @one_year_data, $_ if /$mon1/../$mon2/;
}

close DATAIN;

my ($home_sum,$cell_sum);

foreach (@one_year_data){
my @each_data = split ("\t+", $_);
$each_data[1]=~ s/,//;
$each_data[2]=~ s/,//;
$home_sum += $each_data[1];
$cell_sum += $each_data[2];
my $both_sum = $each_data[1]+$each_data[2];
1 while $both_sum =~ s/(.*\d)(\d\d\d)/$1,$2/;
print "$each_data[0]: $both_sum\n";
}

my $all_sum = $home_sum+$cell_sum;

1 while $home_sum =~ s/(.*\d)(\d\d\d)/$1,$2/;
1 while $cell_sum =~ s/(.*\d)(\d\d\d)/$1,$2/;
1 while $all_sum =~ s/(.*\d)(\d\d\d)/$1,$2/;

print <<TEXT;

固定電話合計 = $home_sum
携帯電話合計 = $cell_sum
総計 = $all_sum
TEXT
    • good
    • 0
この回答へのお礼

返事が遅れまして申し訳ありません。
早速やってみます。

お礼日時:2006/04/19 09:09

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