我有一个文件列表:
TC-00001-(null)-20141027-204159FN.tif
TC-00020-(null)-20141027-203422FN.tif
等
我需要以有序的方式处理这些文件,但不是sort {$a cmp $b}
给出的默认方式。目前,它根据TC-0000X
计算进行排序。
我实际上希望根据204159
字符前的最后一个数字(203422
和FN
)进行排序。这被读作一种简化的时间戳20:14:59 and 20:34:22
。
这些文件的采样频率为1秒,因此该时间戳唯一标识文件。
如何使用此数字对perl进行排序?
答案 0 :(得分:4)
Sort允许您定义按您喜欢的任何算法排序的自定义排序。
所有子需求都返回正数,零或负数 - 非常像cmp
或<=>
。
$a
和$b
是用于此目的的特殊变量。
所以在你的情况下:
#!/usr/bin/perl
use strict;
use warnings;
sub compare_last {
#first we extract the values we're interested in...
my ( $a_last ) = ( $a =~ m/(\d+)FN\./ );
my ( $b_last ) = ( $b =~ m/(\d+)FN\./ );
# print "GOT: $a_last, $b_last, \n";
#then we return the comparison. <=> is numeric, but you could use cmp.
#or manually set your own return codes - sort doesn't care, just bear in mind that
#each element is compared so you can end up with some pretty fruity results if you
#return a random number or something.
return ( $a_last <=> $b_last );
}
print sort compare_last <DATA> ;
## some dummy data
__DATA__
TC-00001-(null)-20141027-204159FN.tif
TC-00020-(null)-20141027-203422FN.tif
TC-00001-(null)-20141027-204159FN.tif
TC-00020-(null)-20141027-123456FN.tif
TC-00001-(null)-20141027-332FN.tif
TC-00020-(null)-20141027-018234FN.tif
答案 1 :(得分:1)
可以使用List::UtilsBy
(与其他List::*
模块一样,使用XS version来提高效率)。
perl -MList::UtilsBy::XS=nsort_by -wle 'print nsort_by { /(\d+)FN[.]/ ? $1 : -1 } <>' filelist.txt