无法从$ File :: Find :: name - perl获取文件的绝对路径
问题描述:
我无法从$ File :: Find :: name获取文件的绝对路径。它显示undef谷值作为输出。无法弄清楚,为什么:(任何一个可以请帮我在显示此
错误是:使用未初始化值$ 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";
}
}
}
答
你的程序布局非常糟糕,如果你正确缩进并使用仔细选择的标识符,编写和调试代码会简单得多:对于一个子程序来说,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);
}
答
正如已经指出,$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";
}
'$文件::查找:: name'才有效在'wanted'函数中。不在其外面。 – dgw 2014-09-02 11:18:18
是否有任何其他方式来获取文件的绝对路径? – user1362796 2014-09-02 11:20:13
您可以在'wanted'子文件中存储完整路径。将'$ _'更改为'$ File :: Find :: name'。虽然可能有更适合这个工作的模块。 – TLP 2014-09-02 12:32:26