我无法从$ File :: Find :: name获取文件的绝对路径。它显示了作为输出的undefale。无法弄清楚原因:(任何人都可以帮我解决这个问题
显示错误:在连接中使用未初始化的值$ file_name
我的代码:
use strict;
use warnings;
use File::Find;
use File::Path qw(make_path);
use File::Copy;
use Cwd;
use Data::Printer;
my $rootPATH = $ARGV[0];
my $id = $ARGV[1];
my @Arraypath;
my $file_name;
our $anr_name;
opendir( my $DIR, $rootPATH );
while ( my $entry = readdir $DIR ) {
next unless -d $rootPATH . '/' . $entry;
next if $entry eq '.' or $entry eq '..';
#print "Found directory $entry\n";
push( @Arraypath, ( split( "\n", $entry ) ) );
}
closedir $DIR;
my $count = 0;
foreach my $line (@Arraypath) {
my $fulllogpath = $rootPATH . "\\" . $line;
#print "$fulllogpath\n";
$count++;
start($fulllogpath);
}
sub start {
my $fulllogpath = shift;
our @content;
#print "$fulllogpath\n\n";
find( \&wanted, $fulllogpath );
sub wanted {
push @content, $_;
return;
}
foreach my $file (@content) {
# print "$file\n\n";
if ( $file =~ /traces[_d]*/ ) {
print "$file\n\n";
$file_name = $File::Find::name;
p $file_name;
print "$file_name\n";
}
}
}
答案 0 :(得分:2)
你的节目布局很差。如果正确缩进并使用精心选择的标识符,编写和调试代码会更简单:子例程的start
之类的名称是无用的。
您还有不必要的子程序声明,它们会破坏程序流并使其难以理解。
为什么你有几个包变量(用our
声明)?通常不需要它们,最好始终使用词法变量,在适当的位置声明,以便所有代码在需要时都可以访问它们。
最好使用File::Spec
来处理文件路径,而不是使用字符串运算符对它们进行操作,因此很容易出错。
管理find
结果的最佳方法是使用绝对路径。看起来你想要做的不仅仅是打印find
返回的结果,因为你加载了Cwd
和File::Copy
这样的模块,但是不知道那个目的是什么我无法帮助你写下来。
此代码删除所有子例程,使一切更简洁。
use strict;
use warnings;
use autodie;
use File::Find 'find';
use File::Spec;
use Data::Printer;
my ($root_path, $id) = @ARGV;
opendir my ($dh), $root_path;
my @dir_list =
grep -d,
map File::Spec->catfile($root_path, $_),
grep { not /\A\.\.?\z/ } readdir $dh;
closedir $dh;
my $count;
for my $dir (@dir_list) {
++$count;
find(sub {
return unless /traces[_d]*/;
my $file = $_;
print "$file\n\n";
my $file_name = $File::Find::name;
p $file_name;
print "$file_name\n";
}, $dir);
}
答案 1 :(得分:0)
如前所述,$File::Find::name
仅在wanted
函数内有效。不在它之外。
但是,我建议转而使用Path::Class
和Path::Class::Rule
以跨平台兼容的方式更简单地处理文件:
use strict;
use warnings;
use Data::Printer;
use Path::Class;
use Path::Class::Rule;
my ( $root_path, $id ) = @ARGV;
my $dir = dir($root_path);
my $next = Path::Class::Rule->new->file->name(qr{traces[_d]*})->iter(
grep { $_->is_dir() } $dir->children
);
while ( my $file = $next->() ) {
# Accomplishes the same as your script. I suspect these prints statements are mostly for debugging though.
print $file->basename(), "\n\n";
p "$file";
print "$file\n";
}