2013-06-18 61 views
-1

我需要使用perl從文本文件讀入DOW YYYY-MM-DD H:MM:SS.S,然後輸出十進制分鐘MM.MMMM 。由於輸入的文本文件perl將H:MM:SS轉換爲MM.MMMM

Fri 2013-06-14 0:59:15.3 
Sat 2013-06-15 1:01:30.6 
Sun 2013-06-16 1:03:45.9 

我要計算小數點分鐘值

(60*0)+59+(15.3/60) = 59.2550 
(60*1)+01+(30.6/60) = 61.5100 
(60*1)+03+(45.6/60) = 63.7600 

,然後輸出

(59.2550, 61.5100, 63.7600) 
+1

不是所有的分鐘都有60秒,所以你的答案可能會在你的方法中被秒掉。 – ikegami

回答

3

假設上的文本文件中的每一行是它自己的一個日期,並且您正在閱讀的文件位於同一個目錄中,並稱爲input.txt,我會這樣做:

use strict; 
use warnings; 

my @result =(); 

{ 
    open (my $file, "<", "input.txt") or die "cannot open < input.txt: $!"; 
    while(<$file>){ 
    my @current = split(/:/,substr($_,15)); 
    push(@result, (60*$current[0]) + $current[1] + ($current[2]/60)); 
    } 
} 

print "(" . join(',',@result) . ")"; 
+1

您應該使用詞法文件句柄和三參數打開。 – simbabque

+0

@simbabque好點,我只是根據你的好建議改進了我的答案,並使代碼更好... – DarkAjax

+1

你還應該'使用strict'和'use warnings';檢查你的'open'和'die'是否成功,如果它失敗,包含'$!'的字符串;並使用正則表達式'/:/'作爲split的第一個參數。 – Borodin

3

輸入文件的格式不是很清楚,但這似乎產生你想要的。它期望輸入文件的路徑作爲命令行參數。

use strict; 
use warnings; 

my @minutes; 
while (<>) { 
    push @minutes, $1*60 + $2 + $3/60 if /(\d+):(\d+):([\d.]+)/; 
} 

printf "(%s)\n", join ', ', map sprintf('%.4f', $_), @minutes; 

輸出

(59.2550, 61.5100, 63.7650) 
+0

'$ 1 * 24'應該是'$ 1 * 60'而不是因爲小時 - >分鐘 – doubleDown

+0

@doubleDown:你對c 。謝謝。 – Borodin

+0

$ cat ./elapsed_01.txt Fri 2013-06-14 0:59:15.3 Sat 2013-06-15 1:01:30.6 Sun 2013-06-16 1:03:45.9 $ ./convert_to_min_03。 pl ./elapsed_01.txt –

0

首先,你必須捕捉到你的輸入:

my $time = "Fri 2013-06-14 0:59:15.3"; 
$time =~ /(\d+?):(\d+?):(.+)$/ #The time captured in three components 
my $hours = $1; 
my $minute = $2; 
my $seconds = $3; 

regular expression描述要匹配你行的。 $意味着將我的表情固定在行尾。 (..)是捕獲組。這些捕獲了我的正則表達式中匹配的內容,並通過$1,$2$3變量使它們可用。

如果你從來沒有學過正則表達式,你應該。正則表達式非常強大,您應該在上面的鏈接中閱讀它們,或者嘗試使用Perldoc tutorial

現在,我有不同的件我的時間來捕獲(並假設60秒分鐘60分鐘小時),我現在可以做我的計算:

my $time_in_seconds = ($hours * 3600) + ($minutes * 60) + $seconds; 
my $time_in_minutes = $time_in_seconds/60; 

司的計算機上具有測量精度的問題,因爲它是很難用基數2表示小數。因此,我寧願將其全部乘以,然後除以60.

一旦您有時間,您需要以您想要的格式打印出來。這就要求printf

printf "%9.4f\n", $time_in_minutes; 

%9.4f指定的格式。 f表示這是一個浮點數(基本上是一個非整數)。 4表示小數位數。 9表示字段寬度,其中包含小數點,小數點另一邊的四個和負號。因此,這將允許高達-9999.999的寬度,這已經足夠了。

把它放在一起....

#! /usr/bin/env perl 
# 
use warnings; 
use strict; 
use feature qw(say); 

while (my $time = <DATA>) { 
    chomp $time; 
    $time =~ /(\d+?):(\d+?):(.+)$/; #The time captured in three components 
    my $hours = $1; 
    my $minutes = $2; 
    my $seconds = $3; 
    my $time_in_seconds = ($hours * 3600) + ($minutes * 60) + $seconds; 
    my $time_in_minutes = $time_in_seconds/60; 
    printf qq(%9.4f\n), $time_in_minutes; 
} 

__DATA__ 
Fri 2013-06-14 0:59:15.3 
Sat 2013-06-15 1:01:30.6 
Sun 2013-06-16 1:03:45.9 

現在運行它:

$ ./test.pl 
    59.2550 
    61.5100 
    63.7650 

看起來是正確的。