我想按名称排序/打印目录中的文件。我的代码列出了所有代码,但排序是偏斜的。这是我的代码和结果。任何建议都会受到欢迎!
my $file;
opendir (DIR, "$dir");
while ($file = readdir(DIR)) {
push (my @files, $file);
@files = sort {$a cmp $b} @files; #NOT sorting!
foreach $file (@files) {
print "$file\n";
}
}
以下是“排序”结果:
Screenshot-Chess_-_Human_versus_GNUchess.png
test.html
katyperry.gif
test.cgi
Californication.S04E05.HDTV.XviD-ASAP.avi
FreeWatch_13.exe
proxy.jpg
test.pl-
.
attachment2.jpg
attachment.jpg
Californication.S04E06.HDTV.XviD-LOL.avi
Californication.S04E07.HDTV.XviD-LOL.avi
boxter.jpg
..
答案 0 :(得分:11)
您正在构建一系列单元素列表,对每个列表进行排序(这是一个无操作)并打印它。你想要做的是将整个文件列表读入一个列表,然后对其进行排序,如下所示:
my $file;
my @files;
opendir (DIR, "$dir");
while ($file = readdir(DIR)) {
push (@files, $file);
}
@files = sort {$a cmp $b} @files;
foreach $file (@files) {
print "$file\n";
}
答案 1 :(得分:5)
另一种方法,使用File::Slurp
use warnings;
use strict;
use File::Slurp;
use Data::Dumper;
my @files = read_dir($dir);
@files = sort @files;
print Dumper(\@files);
这将负责打开和关闭目录,检查是否成功, 并自动排除特殊。和..目录,你可能 不想要。
答案 2 :(得分:3)
my @files
循环在词法范围内的 while
将始终导致在循环的每次迭代中创建新的@files
数组。因此,@files
在任何时候都只包含一个元素,因此排序无意义。 Now see Anomie's answer
答案 3 :(得分:2)
说真的,你做的工作比你要多得多。
use warnings;
use strict;
use autodie;
use File::Spec::Functions qw'no_upwards';
my $dir = '.';
opendir my($dh), $dir;
for my $file ( no_upwards sort readdir $dh ){
print "$file\n";
}
closedir $dh;
答案 4 :(得分:1)
排序路径很棘手,因为在ASCII整理顺序中,路径分隔符斜杠(/)位于大多数路径字符之前,但不是之前,最明显的是点和短划线。
通过在斜杠上拆分将路径分解为路径元素。比较路径元素与cmp的字母数字。如果它是一个平局,那么具有较少元素的路径将位于具有更多元素的路径之前。
请务必选择任何换行符。使用& bypath子例程和Perl sort命令:sort bypath @files;
sub bypath {
my @a = split m'/', $a;
my @b = split m'/', $b;
for ( my $i = 0; $i<=$#a; $i++ ) {
last if $i > $#b;
return $a[$i] cmp $b[$i] if $a[$i] cmp $b[$i];
}
return $#a <=> $#b;
}
示例结果:
答案 5 :(得分:0)
use v5.10;
say for sort do { opendir( my $fh, $dir ); readdir($fh) };
答案 6 :(得分:0)
我不明白为什么你们这么复杂。这适用于排序文件或文件夹。
opendir (my $DIR, "$dir") || die "Error while opening $dir: $!\n";
foreach my $dirFileName(sort readdir $DIR)
{
next if $dirFileName eq '.' or $dirFileName eq '..';
print("fileName: $dirFileName ... \n");
}