在Perl中对文件名进行排序?

g_p*_*ffo 2 sorting perl file-io

我正在Perl中编写一个脚本,我希望.csv在给定目录中的所有文件上运行.文件的名称是:CCCC0.csv, CCCC1.csv, ..., CCCC198.csv.但是,我希望Perl首先在文件CCCC0.csv上运行脚本,而不是在CCCC1.csv等...所以,基本上,根据文件名末尾的数字的增加值.如果我写:

#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

my $file;
my @files = <*.csv>;
my @orderedfiles = sort @files;
for $file (@orderedfiles) {

... do stuff

}
Run Code Online (Sandbox Code Playgroud)

如果我写的话,它首先运行CCCC100.csv而不是运行CCCC11.csv

#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

my $file;
my @files = <*.csv>;
my @orderedfiles = sort { substr($a, 4) <=> substr($b, 4)  } @files;
for $file (@orderedfiles) {

... do stuff

}
Run Code Online (Sandbox Code Playgroud)

它给了我一个错误,告诉我我没有订购数字(我认为他不明白它是4个字符之后的数字而不是另一个字符.)我看过Stackoverflow或perlmonks上的无数问题处理排序但我无法找到我的问题的答案.

编辑:我正在使用Windows机器.

Jos*_*hua 6

你几乎就在那里......".CSV"仍在那里.使用正则表达式读取数字字符会更好.

my @sorted = sort { ($a =~ /(\d+)/)[0] <=> ($b =~ /(\d+)/)[0] } @files;
Run Code Online (Sandbox Code Playgroud)

有一个叫做Schwartzian变换的成语,也可以做到这一点,虽然它需要CS专业才能理解:D

my @sorted = map  { $_->[0] }             # return the sorted file names
                                          #
             sort { $a->[1] <=> $b->[1] } # sort on the numeric portion
                                          #
             map  { [$_, /(\d+)/] }       # wrap the file names in a temporary 
             @files;                      #   array with their numeric portions.

                                          # ^^ read from bottom to top ^^
Run Code Online (Sandbox Code Playgroud)