我尝试在循环中使用此条件(-d $var)
来检查给定目录中有多少个子目录,但是某些文件夹被检测为文件。无法识别目录的情况怎么了?我该如何解决这个问题?
我的代码是:
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`;
}
答案 0 :(得分:2)
我没有看到任何明显的东西。但是,我确实发现了一个错误。
my $new_name = s/\s//g;
。您有=
而不是=~
。$new_name
进行替换。这些都不是你自己的问题。
另一种可能性是你使用三种不同的测试。我想知道你是否以某种方式遇到-d
通过的情况,但其他条件不正确。你可能想把它们分开。
我还注意到您测试该文件是否是$file
的目录,但是当您将目录名放入@Dir
数组时,请将其添加到$pwd
前面。这里发生了什么?你还需要做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:
语句可让您查看代码中发生的更多信息,并帮助您找到逻辑问题。大约1/2时间问题不在程序中,而是在数据中。
答案 1 :(得分:1)
这件事发生在我身上一段时间后,写了一个类似于此的脚本。尝试使用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
}
答案 2 :(得分:1)
您的代码存在许多问题。为什么你认为-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 $!;
}
}