0

我需要帮助在 perl 中排序。我有一个这种格式的日期数组。DD-MMM-YY。示例 19-FEB-12。

我已经花了很多时间,但无法让它工作。我对 perl 也很陌生。感谢您提供任何帮助。谢谢!!

4

6 回答 6

10

这可以使用Time::Piece核心模块的strptime方法来解码日期并根据生成的纪元秒数对它们进行排序。

这个程序演示了这个想法。

use strict;
use warnings;

use Time::Piece;

my @dates = <DATA>;
chomp @dates;

my @sorted = sort {
  Time::Piece->strptime($a, '%d-%b-%y') <=> Time::Piece->strptime($b, '%d-%b-%y')
} @dates;

print "$_\n" for @sorted;

__DATA__
05-FEB-12
10-MAR-11
22-AUG-11
26-FEB-12
10-NOV-12
07-JUN-11
20-APR-12
19-DEC-12
17-JAN-11
25-NOV-11
28-FEB-11
04-SEP-11
03-DEC-12
16-SEP-12
31-DEC-11
08-JUN-11
22-JUN-12
02-AUG-12
23-SEP-11
14-MAY-11

输出

17-JAN-11
28-FEB-11
10-MAR-11
14-MAY-11
07-JUN-11
08-JUN-11
22-AUG-11
04-SEP-11
23-SEP-11
25-NOV-11
31-DEC-11
05-FEB-12
26-FEB-12
20-APR-12
22-JUN-12
02-AUG-12
16-SEP-12
10-NOV-12
03-DEC-12
19-DEC-12
于 2012-06-11T21:35:08.310 回答
3

一种简单的方法是将日期转换为YYYYMMDD可以按字典顺序排序的格式。

请注意,MM应该是表示为两位数的月份。

于 2012-06-11T21:22:04.993 回答
1

您可以使用核心模块Time::Piece将 DD-MMM-YY(或任何输入格式)转换为 ISO 8601 格式。这允许简单的排序。这个例子建立了一个原始数据数组,其中包括 ISO 值作为排序键;对其进行排序;并按排序顺序返回数据:

#!/usr/bin/env perl
use strict;
use warnings;
use Time::Piece;
my $t;
my @data;
while (<DATA>) {
    chomp;
    $t = Time::Piece->strptime( $_, "%d %b %y" );
    push @data, [ $t->datetime, $_ ];    #...ISO 8601 format...
}
my @sorteddata = sort { $a->[0] cmp $b->[0] } @data;
for my $value (@sorteddata) {
    print $value->[1], "\n";
}
__DATA__
19 Feb 12
17 Aug 11
31 Mar 10
01 Aug 11
08 Apr 11
29 Feb 11
于 2012-06-11T21:34:05.983 回答
1

这是仅使用基本 Perl(无模块)的一种可能方法:

#! perl -w

use strict;

my @dates = ( '19-FEB-12', '15-APR-12', '13-JAN-11' );

# map month names to numbers
my %monthnum = ( 
    'JAN' => 1, 'FEB' => 2, 'MAR' => 3, 'APR' => 4,
    'MAY' => 5, 'JUN' => 6, 'JUL' => 7, 'AUG' => 8,
    'SEP' => 9, 'OCT' => 10, 'NOV' => 11, 'DEC' => 12 
    );


# sort the array using a helper function
my @sorted_dates = sort { convert_date($a) cmp convert_date($b) } @dates;

print join(", ", @sorted_dates), "\n";
# outputs: 13-JAN-11, 19-FEB-12, 15-APR-12

exit(0);

# THE END



# converts from 19-FEB-12 to 120219, for sorting
sub convert_date
{
    my $d1 = shift;
    my $d2;

    if ($d1 =~ /(\d{2})-([A-Z]{3})-(\d{2})/)
    {
        $d2 = sprintf( "%02d%02d%2d", $3, $monthnum{$2}, $1 );
    }
    else
    {
        die "Unrecognized format: $d1";
    }

    return $d2;
}

这取决于您的日期格式是否正确,但添加更多验证应该是微不足道的。

于 2012-06-11T21:37:30.800 回答
0

使用日期时间模块;或使用带有月份选项的排序命令 (*nix);或将 dd-mmm-yyyy 转换为 yyyymmdd 然后排序;

于 2012-06-11T21:49:05.417 回答
-2

完全从头开始:

打印输出:

Unsorted:
14-OCT-06
15-OCT-06
13-OCT-06
19-FEB-12
29-DEC-02
15-JAN-02

Sorted (Least recent to most recent):
15-JAN-02
29-DEC-02
13-OCT-06
14-OCT-06
15-OCT-06
19-FEB-12

代码:

#!C:\Perl64

#Input Strings
@inputs = ('14-OCT-06','15-OCT-06','13-OCT-06', '19-FEB-12', '29-DEC-02', '15-JAN-02');

print "Unsorted:\n";
foreach(@inputs){
    print $_."\n";
}

# Hash for Month : Number
%months = ('JAN' => '01',
         'FEB' => '02',
         'MAR' => '03',
         'APR' => '04',
         'MAY' => '05',
         'JUN' => '06',
         'JUL' => '07',
         'AUG' => '08',
         'SEP' => '09',
         'OCT' => '10',
         'NOV' => '11',
         'DEC' => '12');
# Hash for Number : Month
%revmonths = ('01'=>'JAN',
         '02' => 'FEB',
         '03' => 'MAR',
         '04' => 'APR',
         '05' => 'MAY',
         '06' => 'JUN',
         '07' => 'JUL',
         '08' => 'AUG',
         '09' => 'SEP',
         '10' => 'OCT',
         '11' => 'NOV',
         '12' => 'DEC');

# Rearrange the order to 'Year-Month-Day'
@dates = ();
foreach(@inputs){
    my @split = split('-',$_);
    my @rearranged = reverse(@split);
    @rearranged[1] = $months{$rearranged[1]};
    push(@dates, \@rearranged);
}

# Sort based on these three fields
@sorted = sort { $a->[2] <=> $b->[2] } @dates;
@sorted = sort { $a->[1] <=> $b->[1] } @sorted;
@sorted = sort { $a->[0] <=> $b->[0] } @sorted;

# Replace Month Number with Month name
$size = @sorted;
for $counter (0..$size-1){
    my $ref = $sorted[$counter];
    my @array = @$ref;
    my $num = $array[1];
    $array[1] = $revmonths{$array[1]};
    my @array = reverse(@array);
    $sorted[$counter] = \@array;
}

print "\nSorted (Least recent to most recent):\n";
foreach(@sorted){
    my @temp = @$_;
    my $day = $temp[0];
    my $month = $temp[1];
    my $year = $temp[2];
    print $day."-".$month."-".$year;
    print "\n";
}
于 2012-06-11T22:28:24.623 回答