Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Perl对目录文件名进行排序_Perl_Sorting - Fatal编程技术网

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

使用Perl对目录文件名进行排序,perl,sorting,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 "

我想按名称对目录中的文件进行排序/打印。我的代码列出了它们,但是排序是不正确的。这是我的代码和结果。欢迎提出任何建议

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

您正在构建一系列单元素列表,对每个列表进行排序(这是一个no-op)并打印它。您要做的是将整个文件列表读取到一个列表中,然后对其进行排序,如下所示:

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";
}

while
循环的词法范围内的
my@files
将始终导致在循环的每次迭代中创建一个新的
@files
数组。因此,在任何时候,
@文件
将只包含一个元素,因此排序毫无意义

另一种方法,使用

这负责打开和关闭目录,检查是否成功, 并自动排除特殊情况。和。。目录,您可能
不想要。

说真的,你做的工作比你必须做的多得多

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;

排序路径很棘手,因为在ASCII排序序列中,路径分隔符斜杠(/)在大多数路径字符之前,但不是在所有路径字符之前,最明显的是点和破折号

通过在斜线上拆分,将路径拆分为路径元素。将路径元素与cmp进行字母数字比较。如果是平局,那么元素较少的路径优先于元素较多的路径

一定要咬掉任何新词。结合Perl sort命令使用&bypath子例程: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;
  }
子路径{
my@a=拆分m'/',$a;
my@b=拆分m'/',$b;
对于(我的$i=0;$i$#b;
如果$a[$i]cmp$b[$i],则返回$a[$i]cmp$b[$i];
}
返回$#a$#b;
}
样本结果:

  • 这个
  • 这个/那个
  • 这个/那个/其他
  • 这个/那个/其他/文件a
  • 这个/那个/其他/fileb
  • this/that/other.new/filea

我不明白你们为什么这么复杂。这非常适合对文件或文件夹进行排序

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

更好的方法是,用
@files=readdir(DIR)
@andy lester替换
while
循环,因为这样,
打印连接(“\n”,排序{$a cmp$b}readdir(DIR))。“\n”
谢谢!我真不敢相信我错过了这么基本的东西。感谢StackOverflow和所有帮助我解决问题的人!同时添加
lc
函数避免了名称大写引起的奇怪结果:@files=sort{lc($a)cmp lc($b)}@files;
use v5.10;
say for sort do { opendir( my $fh, $dir ); readdir($fh) };
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");
}