Perl5で同時刻のデータを統合したい
perl初心者です。
下記のような同時刻の2つのデータを1つのデータに統合させたいのですが
うまく出来ず困っています。
どうかお知恵を貸していただけないでしょうか。
データは時刻(時:分:秒), 値1, 値2になっています。
test1.txtの同時刻の後ろにtest2.txtの値1と値2を入れ、
欠測値には-999を入れるプログラムを作っています。
厄介なのは、
開始時刻がtest1.txtよりtest2.txtが早い場合や
終了時刻がtest2.txtよりtest1.txtが遅い場合がある事です。
test1.txt
10:13:14, 3.1, 0.1
10:13:15, 6.1, 0.3
10:13:16, 8.7, 0.2
10:13:17, 12.8, 0.3
10:13:18, 13.4, 0.5
10:13:19, 15.2, 0.4
test2.txt
10:13:16, 32.5, 0.01
10:13:17, 33.1, 0.03
10:13:18, 36.2, 0.02
10:13:19, 34.3, 0.01
10:13:20, 33.8, 0.04
10:13:21, 32.6, 0.09
10:13:22, 32.1, 0.08
希望結果
test.txt
10:13:14, 3.1, 0.1, -999.0, -999.00
10:13:15, 6.1, 0.3, -999.0, -999.00
10:13:16, 8.7, 0.2, 32.5, 0.01
10:13:17, 12.8, 0.3, 33.1, 0.03
10:13:18, 13.4, 0.5, 36.2, 0.02
10:13:19, 15.2, 0.4, 34.3, 0.01
10:13:20, -999.0, -999.0, 33.8, 0.04
10:13:21, -999.0, -999.0, 32.6, 0.09
10:13:22, -999.0, -999.0, 32.1, 0.08
以下が自分が作成したプログラムです。
open IN_1, "test1.txt";
open IN_2, "test2.txt";
open OUT, ">test.txt";
while ($input1 = <IN_1>) { # test1.txtの処理
chomp $input1; # 改行削除
@input1 = split(/,/, $input1); # カンマ区切り
$n = $n + 1;
$time1[$n] = @input1[0];
@time1 = split(/:/, $time1[$n]); # 時刻をコロン区切り
@hours1[$n] = @time_l[0];
@min1[$n] = @time_l[1];
@sec1[$n] = @time_l[2];
@a[$n] = @input1[1]; # 値1
@b[$n] = @input1[2]; # 値2
}
while ($input2 = <IN_2>) { # test2.txtの処理
chomp $input2;
@input2 = split(/,/, $input2);
$m = $m + 1;
$time2[$m] = @input2[0];
@time2 = split(/:/, $time2[$m]);
@hours2[$m] = @time2[0];
@min2[$m] = @time2[1];
@sec2[$m] = @time2[2];
@c[$m] = @input2[1]; # 値1
@d[$m] = @input2[2]; # 値2
}
# 開始と終了時刻の計算
# test1.txtの時刻
$hours1_S = @hours1[1]; # 開始時
$hours1_E = @hours1[$n]; # 終了時
$min1_S = @min1[1]; # 開始分
$min1_E = @min1[$n]; # 終了分
$sec1_S = @sec1[1]; # 開始秒
$sec1_E = @sec1[$n]; # 終了秒
$time1_S = $hours1_S*3600 + $min1_S*60 + $sec1_S; # 開始時刻を秒に計算
$time1_E = $hours1_E*3600 + $min1_E*60 + $sec1_E; # 終了時刻を秒に計算
# test2.txtの時刻
$hours2_S = @hours2[1];
$hours2_E = @hours2[$m];
$min2_S = @min2[1];
$min2_E = @min2[$m];
$sec2_S = @sec2[1];
$sec2_E = @sec2[$m];
$time2_S = $hours2_S*3600 + $min2_S*60 + $sec2_S;
$time2_E = $hours2_E*3600 + $min2_E*60 + $sec2_E;
if($time1_S <= $time2_S){ # 開始時刻の比較
$starttime = $time1_S;
}else{
$starttime = $time2_S;
}
if($time1_E <= $time2_E){ # 終了時刻の比較
$endtime = $time2_E;
}else{
$endtime = $time1_E;
}
$j = $endtime - $starttime; # 全体のデータ個数
# test.txtへ出力
for($i=1; $i<=$j; $i++){
if(@hours1[$i] != @hours2[$i] && @min1[$i] != @min2[$i] && @sec1[$i] != @sec2[$i]){
printf OUT "%2d:%2d:%2d %5.1f% 5.1f %5.1f %7.2f\n",
@hours1[$i], @min1[$i], @sec1[$i], @a[$i], @b[$i], -999, -999;
}elsif(@hours1[$i] == @hours2[$i] && @min1[$i] == @min2[$i] && @sec1[$i] == @sec2[$i]){
printf OUT "%2d:%2d:%2d %5.1f% 5.1f %5.1f %7.2f\n",
@hours1[$i], @min1[$i], @sec1[$i], @a[$i], @b[$i], @c[$i], @d[$i];
}else{
printf OUT "%2d:%2d:%2d %5.1f% 5.1f %5.1f %7.2f\n",
@hours2[$i], @min2[$i], @sec2[$i], -999@, -999, @c[$i], @d[$i];
}
}
close IN_1;
close IN_1;
close OUT;
とても汚いプログラムになってしまいました…
このプログラム以外でも構いませんのでどうかよろしくお願い致します。
お礼
需要はあると思うので、そういうソフトを作っている方がいればいいと思いました。 ありがとうございます。