2013-06-18 60 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 

看起来是正确的。