I've looked around here a bit and found similar questions but not exactly. If there is one, I apologize and please point me to it.
I have the following code. I'm trying to create a csv file of simply an ID pulled from a filename and the filename itself. This is the ENTIRE script.
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;
}
The line that prints to the screen, prints perfectly.
If I take the file open/close and the first print statement out of the if
block, it prints that line into the file, but not the data inside the block.
I've tried every combo I can think of and it doesn't work. I've alternated between '>'
and '>>'
since it clearly needs the append since it's looping over filenames, but neither works inside the if
block.
Even this code above doesn't throw the die
errors! It just ignores those lines! I'm figuring there's something obvious I'm missing.
Quoting File::Find::find
's documentation:
Additionally, for each directory found, it will chdir() into that directory
It means that when you open
inside findAllFiles
, you are potentially opening a file filenames.csv
inside a subdirectory of your initial directory. You can run something like find . -name filenames.csv
from your terminal, and you'll see plenty of filenames.csv
. You can change this behavior by passing no_chdir
option to find
:
find( { wanted => \&findAllFiles, no_chdir => 1}, '.');
(and additionally changing >
for >>
in your open)
However, personally, I'd avoid repeatedly opening and closing filenames.csv
when you could open it just once before calling find
. If you don't want to have your filehandle globally defined, you can always pass it as an argument to findAllFiles
:
{
open my $fh, '>', 'filenames.csv' or die "Failed to open 'filenames.csv': $!";
find(sub { findAllFiles($fh) }, '.')
}
sub findAllFiles {
my ($fh) = @_;
...