#!/usr/bin/perl use warnings; use strict; my @data = ('RRsnap02 2013-07-24 12:35:35', 'vmk000 2013-07-22 17:16:50', 'vmk001 2013-07-22 20:00:36', 'vmk009 2013-07-23 18:21:12', 'vmk010 2013-07-23 18:31:00', 'vmk020 2013-07-23 23:30:43', 'vmk024 2013-07-24 03:27:30', 'vmk031 2013-07-24 10:27:36', 'vmk032 2013-07-24 11:27:38', 'vmk032 2013-07-24 11:27:38', ); sub get_date { my $s = shift; $s =~ s/^\S+\s+//; return $s; } # Simple: print "$_\n" for sort { get_date($a) cmp get_date($b) } @data; # Faster, Schwartzian transform, computes get_date just once for each line: print "$_\n" for map $_->[1], sort { $a->[0] cmp $b->[0] } map [ get_date($_), $_ ], @data; # Orcish maneuver, compute get_date only when needed and cache: my %cache; print "$_\n" for sort { ( $cache{$a} //= get_date($a) ) cmp ( $cache{$b} //= get_date($b) ) } @data; # Guttman Rosler Transform, changing to strings for default sort: print "$_\n" for map { s/(.*) (\S+\s+)$/$2$1/; $_ } sort map { s/^(\S+\s+)(.*)/$2 $1/; $_ } @data;