(Perl)如何将字符串转换为日期格式并查找最近的?

tvz2xvvm  于 2022-11-15  发布在  Perl
关注(0)|答案(3)|浏览(315)

我使用的是Perl,有一个输入文件,其中包含多个日期,例如17/04/2021,这些日期是以文本形式写入的。我如何将它们转换为日期格式,然后比较它们,看看哪个是最新的?
输入文件格式:

01/09/2020
23/10/2019
12/06/2022
15/08/2017

Perl脚本:

#! /usr/bin/perl
use warnings;
use strict;
use Data::Dumper;

my $InputFile = "path/to/file.input";
open(FH, '<', $InputFile) or die $!;
while(my $Line = <FH>)
{

}
close(FH);
  • 谢谢-谢谢
piv4azn7

piv4azn71#

格式为yyyymmdd的日期可以直接比较,也可以用数字或词汇进行比较。

use warnings;
use strict;
use feature 'say';
# use List::Util qw(max);

die "Usage: $0 file\n" if not @ARGV;

my @dates;

while (<>) {
    chomp;

    push @dates, join '', reverse split '/';
}

@dates = sort { $a <=> $b } @dates;  # latest: $dates[-1]

say for @dates;

# Or, if only the last one is needed (uncomment 'use' statement)
# my $latest_date = max @dates;

当在标量上下文中使用“菱形运算符”<>时,它逐行读取在命令行上提交的文件。(而不是/\//).它的下一个(可选)参数,即生成要拆分的字符串的表达式,默认为$_变量。另请根据需要参阅reversejoinsortList::Util
也可以在命令行程序(“单行程序”)中执行此操作

perl -wnlE'push @d, join "", reverse split "/"; }{ say for sort @d' file

其中}{表示END { }块的开始。或者,仅表示最新日期

perl -MList::Util=max -wnlE'... }{ say max @d' file

如果你想要更紧凑的,

use warnings;
use strict;
use feature 'say';

say for sort map { chomp; join '', reverse split '/' } <>;

列表上下文中的菱形运算符一次返回所有行,这里它的输出被提供给map,并施加列表上下文。
或在命令行上

perl -wE'say for sort map { chomp; join "", reverse split "/" } <>' file
wwwo4jvm

wwwo4jvm2#

strptime(永远)是您的朋友:

#!/usr/bin/env perl

use 5.12.10;
use Time::Piece;

my $fmt='%d/%m/%Y';
my @t;
while( <DATA> ){
    chop;
    eval { push @t, Time::Piece->strptime($_, $fmt) } or
        say STDERR "Unexpected format in input: $_";
}

say $_->strftime($fmt) foreach sort @t;

__DATA__
01/09/2020
01/09/2020
23/10/2019
12/06/2022
15/08/2017

要以一行程序的形式执行此操作,可以执行以下操作:

perl -MTime::Piece -0777 -aE '$f="%d/%m/%Y";
    say foreach sort { $a <=> $b } map Time::Piece->strptime($_, $f), @F'

一行程序并不完全相同,因为它将在一行中处理多个日期,而脚本严格要求每行只包含一个日期。

sycxhyv7

sycxhyv73#

这里有一种方法:

#! /usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
use Time::Local;

my $InputFile = $ARGV[0];
open(my $fh, '<', $InputFile) or die $!;

## A hash to hold the times so we can sort later
my %seconds;

while(my $Line = <$fh>){
  chomp($Line);
  my ($day, $month, $year) = split(/\//, $Line);
  my $secondsSinceTheEpoch = timelocal(0, 0, 0, $day, $month-1, $year);
  $seconds{$secondsSinceTheEpoch}++
}
close($fh);

my @sortedSeconds = sort {$a <=> $b} keys(%seconds);
print "$sortedSeconds[0]\n";

或者,如果你喜欢简洁:

#! /usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
use Time::Local;

## A hash to hold the times so we can sort later
my %seconds;

while(<>){
  chomp();
  my ($day, $month, $year) = split(/\//);
  $seconds{timelocal(0, 0, 0, $day, $month-1, $year)}++
}

my @sortedSeconds = sort {$a <=> $b} keys(%seconds);
print "$sortedSeconds[0]\n";

在这两种情况下,都需要将文件作为参数传递给脚本:

$ foo.pl file
1502744400

相关问题