# matching2_hash.pl
# 内容 : マッチングプログラム（２ファイルの１対ｎマッチングプログラム）
# 前提 : マスタファイルとトランザクションファイルの両方とも
#        マッチングするキーごとに昇順に並べ替えておく必要はない
# Copyright (c) 2012 Mitsuo Minagawa, All rights reserved.
# (minagawa@fb3.so-net.ne.jp)
# 使用方法 : c:\>perl matching2_hash2.pl
# 
# 出力用ハッシュ
my %out1;
# エラー出力用ハッシュ
my %out2;
# トランザクションファイルの件数
my $out2_ctr	=	0;

# マスタデータをハッシュに入れる
open(IN1,"master.txt");
while($line1	=	<IN1>) {
	chomp($line1);
#---区切り文字により、処理を変更する----------
#タブ区切りのとき
#			@in1	=	split("\t",$line1);

#カンマ区切りのとき
	my $tmp	=	$line1;
	$tmp	=~	s/(?:\x0D\x0A|[\x0D\x0A])?$/,/;
	@in1	=	map {/^"(.*)"$/ ? scalar($_ = $1, s/""/"/g, $_) : $_}
					($tmp =~ /("[^"]*(?:""[^"]*)*"|[^,]*),/g);
#-----------------
	$in1_key	=	$in1[0];
 # ハッシュに初期値0を代入する
	$out1{$in1_key}	=	[0,0];
}
close(IN1);

# トランザクションデータをハッシュに入れる
open(IN2,"transaction.txt");
while($line2	=	<IN2>) {
	chomp($line2);
#---区切り文字により、処理を変更する----------
#タブ区切りのとき
#			@in2	=	split("\t",$line2);

#カンマ区切りのとき
	my $tmp	=	$line2;
	$tmp	=~	s/(?:\x0D\x0A|[\x0D\x0A])?$/,/;
	@in2	=	map {/^"(.*)"$/ ? scalar($_ = $1, s/""/"/g, $_) : $_}
					($tmp =~ /("[^"]*(?:""[^"]*)*"|[^,]*),/g);
#-----------------
	$in2_key	=	$in2[0];
	$out2_ctr++;
	$w_key	=	$in2_key.sprintf("%08d",$out2_ctr);
# ハッシュのキーがすでに存在する場合、数値を加算する
	if	(exists $out1{$in2_key})	{
		@total	=	@{$out1{$in2_key}};
		$total[0]	+=	$in2[1];
		$total[1]	+=	$in2[2];
		$out1{$in2_key}	=	[@total];
# 集計する項目が1つの場合
#		$out1{$in1_key}	+=	$in2[1];
	}
# ハッシュのキーが存在しない場合
	else	{
		$out2{$w_key}	=	[@in2];
	}
}
close(IN2);

open(OUT1,">matching.txt");
# ハッシュのキーをソートする
foreach my $key (sort keys %out1) {
# 配列のリファレンスを配列に戻し、
# キーと集計結果をタブ区切りで結合し、出力する
	print OUT1 join("\t", $key, @{$out1{$key}})."\n";
}
close(OUT1);

# マッチしないエラーデータの出力
open(OUT2,">tranonly.txt");
# ハッシュのキーをソートする
foreach my $key (sort keys %out2) {
# 配列のリファレンスを配列に戻して出力する
	print OUT2 join("\t", @{$out2{$key}})."\n";
}
close(OUT2);
