目录在perl中被检测为文件

我试图在循环中使用这个条件(-d $var)来检查给定目录上有多less个子目录,但有些文件夹被检测为一个文件。 发生了什么情况,无法识别目录? 我该如何解决这个问题?

我的代码是:

 foreach my $file (@files) { next if($file =~ m/^\./); if (-d $file and -e $file and !$seen{$file}) { $seen{$file} = 1; push @Dir, "$pwd/$file"; } next if ($file !~ m/\s/i); my $new_name = s/\s//g; `mv $pwd/$file $pwd/$new_name`; } 

我没有看到任何明显的。 但是,我确实发现了一个错误。

  • 你有my $new_name = s/\s//g; 。 你有=而不是=~
  • 你也不要说如何得到$new_name来完成替换。

这些都没有指出你的问题本身。

另外一种可能性是你用三种不同的测试结合在一起。 我不知道你是否遇到了-d通过的条件,但是其他条件是不正确的。 你可能想把它们分开。

我也注意到你测试文件是否是一个带有$file的目录,但是当你把目录名放到@Dir数组中时,你可以用$pwd作为@Dir 。 这里发生了什么? if ( -d "$pwd/$file" )也需要做?

我建议你把一些调试语句,看看你有什么问题。

尝试这个:

 use strict; use warnings; use feature qw(say); use File::Copy; my %seen; my @dir; for my $file ( @files ) { say qq(DEBUG: Looking at "$file"); next if $seen{$file}; say qq(DEBUG: "$file" has not been previously seen); $seen{$file} = 1; next if $file =~ /^\./; say qq(DEBUG: "$file" does not start with a period); if ( -d $file ) { say qq(DEBUG: "$file" is a directory); push @dir, "$pwd/$file; } else { #DEBUG: say qq(DEBUG: "$file" is a file); } #DEBUG: my $new_name = $file; if ( $new_name =~ s/\s+//g ) { say qq(DEBUG: Moving file "$file" to "$new_name"); move $file, $new_name or die qq(Couldn't move "$file" to "$new_name"); } } 
  • use feature qw(say); 允许你使用say命令。 这就像print除了它为你打下了新的一页。
  • use File::Copy模块可以让你使用move语句。 没有更多的炮轰和操作系统的依赖。 Perl带有一大堆模块,让你的生活更轻松。 例如, File::Find允许您查找文件和目录。
  • 我将所有的文件和目录包括在%seen (为什么不?),并检查之前,检查是否是一个目录。
  • 我使用move $file, $new_name or die qq(...) ,看看是否移动语句工作。 你应该总是测试你的函数的输出 – 特别是容易出错的函数,比如移动文件名或者复制它等等。
  • 注意if ( $new_name =~ s/\s+//g ) 。 这使我可以测试$new_name是否有空格,并同时删除所有的空格。
  • qq(...)就像是一个双引号,但是你可以在字符串中使用引号而不必引用它们。 这样,我可以看到,如果我的文件名称的名称末尾有空格或NL。

一旦你的代码工作,你可以轻松地搜索字符串DEBUG:并消除噪音。

我没有测试过我的代码(当程序没有完成,我不知道你的数据是什么样子的时候很难),但是我希望你明白。 DEBUG:语句将允许您查看代码中发生的更多事情,并帮助您找到逻辑问题。 大约有一半的时间问题不在程序中,而是在数据中。

这发生在我后面写了一个类似于这个脚本。 尝试使用File :: Spec方法catfile使用整个路径。 我假设你正在一个单独的目录下运行这个实际的文件和目录。

 use Cwd; use File::Spec; my $dir = getcwd; # Or whatever directory name you want my $full_name = File::Spec->catfile($dir, $file); if (-d $full_name) { # Do something } 

你的代码有很多问题。 你为什么认为-d测试失败? 相同的重命名应用于目录和文件; 唯一的区别是在第一次看到目录时,目录被另外推送到@dir数组中。

我不清楚你想要做什么,但是这个版本只重命名名称中包含空格字符的文件。

 foreach my $file (@files) { next if $file =~ m/^\./; if (-d $file ) { push @dir, "$pwd/$file" unless $seen{$file}++; next; } my $new_name = $file; if ($new_name =~ s/\s//g) { rename "$pwd/$file", "$pwd/$new_name" or warn $!; } }