-1

我需要使用 perl 从文本文件 DOW YYYY-MM-DD H:MM:SS.S 中读取,然后输出十进制分钟 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)
4

3 回答 3

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) . ")";
于 2013-06-18T14:44:42.823 回答
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)
于 2013-06-18T15:37:50.470 回答
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;

则表达式描述了你想在你的行上匹配的内容。这$意味着将我的表情固定在行尾。是(..)捕获组。这些捕获在我的正则表达式中匹配的内容,并通过 、 和 变量使$1它们$2可用$3

如果您从未学习过正则表达式,那么您应该学习。正则表达式非常强大,您应该在上面的链接中阅读它们,或者尝试Perldoc 教程

现在,我已经捕获了各种时间片段(假设 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

看起来是对的。

于 2013-06-18T19:02:54.477 回答