我在这里看了一下,发现了类似的问题,但并不完全相同。如果有,我道歉,请指出我。
我有以下代码。我正在尝试创建一个简单地从文件名和文件名本身拉出的ID的csv文件。这是整个脚本。
use strict;
use warnings;
use File::Find;
find( \&findAllFiles, '.');
exit;
sub findAllFiles {
my @fp1;
my @fp2;
my $patId;
my $filename;
my $testvar = "hello again";
$filename = $File::Find::name;
if ($filename =~ /\.pdf$/) {
open (my $fh, '>', 'filenames.csv') or die "Failed to open - $!\n";
print $fh "starting...$testvar\n" or die "Failed to print to file - $!\n";
@fp1 = split('/', $filename);
@fp2 = split('_', $fp1[-1]);
$patId = $fp2[-1];
$patId =~ s/\.pdf$//;
print "Adding $patId, file = $filename\n";
print $fh "$patId,$filename\n" or die "File print error: $!";
close $fh or warn "close failed! - $!";
}
return;
}
打印到屏幕的线条完美打印。如果我从if
块中取出文件open / close和第一个print语句,它会将该行打印到文件中,但不会打印到块内的数据。我已经尝试了我能想到的每一个组合,它不起作用。我在'>'
和'>>'
之间交替,因为它显然需要追加,因为它循环遍历文件名,但在if
块内都不起作用。
即使上面的代码也没有抛出die
错误!它只是忽略了那些线!我觉得有一些明显的东西我不知道了。
引用File::Find::find
的文档:
此外,对于找到的每个目录,它将chdir()放入该目录
这意味着当您在open
中使用findAllFiles
时,您可能会在初始目录的子目录中打开文件filenames.csv
。你可以从你的终端运行像find . -name filenames.csv
这样的东西,你会看到很多filenames.csv
。您可以通过将no_chdir
选项传递给find
来更改此行为:
find( { wanted => \&findAllFiles, no_chdir => 1}, '.');
(另外在你的公开场合改变>
为>>
)
但是,就个人而言,当你在打电话给filenames.csv
之前打开它时,我会避免反复打开和关闭find
。如果您不希望全局定义文件句柄,则始终可以将其作为参数传递给findAllFiles
:
{
open my $fh, '>', 'filenames.csv' or die "Failed to open 'filenames.csv': $!";
find(sub { findAllFiles($fh) }, '.')
}
sub findAllFiles {
my ($fh) = @_;
...
filenames.csv将在找到pdf的目录中创建,因为find()会在搜索时更改目录。如果这不是您想要的,请使用绝对路径打开它(或在调用find之前打开它,这似乎是一个更好的主意)。