如何根据文件名的一部分对文件列表进行排序?

时间:2013-08-13 08:26:22

标签: perl sorting

我有一个数组(@pssm_list),其中包含这样的文件

1.nr.pssm
2.nr.pssm
3.nr.pssm
4.nr.pssm
5.nr.pssm
6.nr.pssm
7.nr.pssm

文件列表的名称为1.nr.pssm226.nr.pssm

我尝试使用sort(@pssm_list),但顺序不是从1到226

所以我尝试编写像这样的代码

opendir(pssm_handle,$ARGV[0]);
@pssm_list = grep(/\.pssm/,readdir(pssm_handle));

$tag = 0;
until($tag > 226)
{
        foreach $file (@pssm_list)
        {
                @Temp = split("[.]",$file);
                if($Temp[0] == $tag)
                {
                        push(@Sorted,join("",$file));
                }
        }
        $tag++;
}

我想知道是否存在任何解决方案可以在一行中对列表进行排序?

3 个答案:

答案 0 :(得分:5)

我也遇到了这个问题,我使用了这个名为Sort::Naturally的软件包帮我正确排序数字。

  

在自然排序下,数字子串以数字方式进行比较,其他单词字符在词汇上进行比较。

答案 1 :(得分:3)

我认为应该这样做:

@Sorted = sort { int( $a ) <=> int( $b ) } @pssm_list;

这取决于int()的宽容性,例如int( "99xyz" ) == 99

如果你的文件名更复杂,你应该用提取数字部分的函数调用替换int( $a ),或者按照mpapec的建议使用map

编辑:我的第一次尝试已经过时了,抱歉,在Ruby工作的时间太长,无法记住正确的Perl语法!

答案 2 :(得分:3)

my @pssm_list = 
  map $_->[0],
  sort { $a->[1] <=> $b->[1] }
  map [ $_, /(\d+)/ ],
  grep(/\.pssm/,readdir(pssm_handle));

或稍微低效的排序:

my @pssm_list =
  sort { 
    my ($x,$y) = map /(\d+)/, ($a,$b); 
    $x <=> $y;
  }
  grep(/\.pssm/,readdir(pssm_handle));