使用Perl对目录文件名进行排序

时间:2011-02-26 04:10:13

标签: perl sorting

我想按名称排序/打印目录中的文件。我的代码列出了所有代码,但排序是偏斜的。这是我的代码和结果。任何建议都会受到欢迎!

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  
..  

7 个答案:

答案 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;
  }

示例结果:

  • 这/那
  • 这/那/其他
  • 这/那/其他/ filea中
  • 这/那/其他/ FILEB
  • 这/那/ other.new / filea中

答案 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");
}