在 Perl 中对文件名进行排序?
Sorting names of files in Perl?
我正在用 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
}
它首先 运行 在 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
}
它给我一个错误,告诉我我没有订购数字(我假设他不明白这是 4 个字符之后的数字而不是另一个字符。)
我已经查看了关于 Whosebug 或 perlmonks 的无数问题,但我一直无法找到我的问题的答案。
编辑:我正在使用 windows 机器。
我相信 substr($a, 4) 在您的示例中返回“100.csv”,因此您仍然需要 trim 关闭它的 .csv 后缀。
您快到了...“.CSV”仍然存在。最好使用正则表达式来读取数字字符。
my @sorted = sort { ($a =~ /(\d+)/)[0] <=> ($b =~ /(\d+)/)[0] } @files;
有一个成语叫Schwartzian Transform也可以做到这一点,虽然它需要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 ^^
您可以 Sort::Key::Natural 试一试。来自简介:
use Sort::Key::Natural qw(natsort);
my @data = qw(foo1 foo23 foo6 bar12 bar1
foo bar2 bar-45 foomatic b-a-r-45);
my @sorted = natsort @data;
print "@sorted\n";
# prints:
# b-a-r-45 bar1 bar2 bar12 bar-45 foo foo1 foo6 foo23 foomatic
我正在用 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
}
它首先 运行 在 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
}
它给我一个错误,告诉我我没有订购数字(我假设他不明白这是 4 个字符之后的数字而不是另一个字符。) 我已经查看了关于 Whosebug 或 perlmonks 的无数问题,但我一直无法找到我的问题的答案。
编辑:我正在使用 windows 机器。
我相信 substr($a, 4) 在您的示例中返回“100.csv”,因此您仍然需要 trim 关闭它的 .csv 后缀。
您快到了...“.CSV”仍然存在。最好使用正则表达式来读取数字字符。
my @sorted = sort { ($a =~ /(\d+)/)[0] <=> ($b =~ /(\d+)/)[0] } @files;
有一个成语叫Schwartzian Transform也可以做到这一点,虽然它需要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 ^^
您可以 Sort::Key::Natural 试一试。来自简介:
use Sort::Key::Natural qw(natsort);
my @data = qw(foo1 foo23 foo6 bar12 bar1
foo bar2 bar-45 foomatic b-a-r-45);
my @sorted = natsort @data;
print "@sorted\n";
# prints:
# b-a-r-45 bar1 bar2 bar12 bar-45 foo foo1 foo6 foo23 foomatic