※ 引述《CindyLinz (Cindy Wang)》之銘言:
: ※ 引述《asiagodfater (亞洲統粉前來報到)》之銘言:
: : 無奈於小弟是程設新手,最菜的那種
: : 目前想要把同天同小時的資料做平均然後輸出
: : 目前寫成這樣
: : 不知道錯在哪裡
: : http://pastebin.com/Fnxs2Jdk
: : 不知道有沒有大哥大姐可以給點指導,程式碼內註解掉的部分為原始資料的一小部分
: : 求解求幫助
: 你每一次 <$fh> 的動作會從檔案中讀進來新的一行,
: 你原本的寫法可能會每區漏掉一行..
: goto 在沒特別好處的時候少用比較好~
: 然後, use strict 與 use warnings 開起來通常會是好習慣~
: 最後面是我試作的程式:
: 用 <DATA> 可以把 __DATA__ 後面的東西當成檔案讀進來,
: regex 可以只 capture 你要的部分, 這樣就比較不需要去數 capture 的編號了.
: 然後, regex 裡面的 . 是特殊字元, 加一下反斜線比較好.
: 我在日期與小時的部分是把年月日時四個欄位一起抓進來,
: 所以要用 eq 這種字串比對.
: while( <ooxx> ) 這樣寫法, 在 while 裡面沒指定讀進來的東西要放哪, 會讀一行進 $_
: if( /ooxxooxx/ ) 這樣寫法, 沒有指定 regex 要跟誰比對, 會跟 $_ 比對
: 不過如果程式複雜的話, 這種寫法會讓 $_ 重複地被蓋來蓋去就是不好的習慣了~
: print 要印的東西如果想要包含一點點計算, 像是我需要一個除法來作平均,
: 可以讓 print 印好幾項, 將這個計算的 expression 獨立放置, 不要塞在字串裡面~
: 最後, 我不是大姐, 不准叫我大姐~ v_v
: #!/usr/bin/perl
: use strict;
: use warnings;
: my($key, $sum, $count) = ('', 0, 0);
: while( <DATA> ) {
: if( /(\d+-\d+-\d+-\d+):\d+:\d+ (\d+\.\d+)/ ) {
: if( $1 eq $key ) {
: $sum += $2;
: ++$count;
: }
: else {
: if( $count ) {
: print "$key ", $sum/$count, "\n";
: }
: $key = $1;
: $sum = $2;
: $count = 1;
: }
: }
: }
: if( $count ) {
: print "$key ", $sum/$count, "\n";
: }
: __DATA__
: 2017-3-7-0:16:20 3.030
: 2017-3-7-0:18:21 2.857
: 2017-3-7-0:20:20 2.870
: 2017-3-7-0:22:20 2.991
: 2017-3-7-0:24:20 3.118
: 2017-3-7-1:45:20 3.152
: 2017-3-7-1:31:20 3.421
: 2017-3-8-1:45:20 2.665
: 2017-3-8-1:31:20 5.765
改用hash 來做, 如果日期非順序性可以考慮看看:
#!/usr/bin/perl
%date = ();
%key_cnt = ();
while (<DATA>) {
if (/(\d+-\d+-\d+-\d+):\d+:\d+ (\d+\.\d+)/) {
$key_cnt{$1}++;
if (exists $date{$1}) {
$date{$1} += $2;
} else {
$date{$1} = $2;
}
}
}
foreach $key(sort keys %date) {
if (exists $key_cnt{$key}) {
print $key," => ",$date{$key}/$key_cnt{$key},"\n";
}
}
__DATA__
2017-3-7-0:16:20 3.030
2017-3-7-0:18:21 2.857
2017-3-7-0:20:20 2.870
2017-3-7-0:22:20 2.991
2017-3-7-0:24:20 3.118
2017-3-7-1:45:20 3.152
2017-3-7-1:31:20 3.421
2017-3-8-1:45:20 2.665
2017-3-8-1:31:20 5.765