Reputation: 79
I have a Perl program to read .html's and only works if the program is in the same directory as the .html's.
I would like to be able to start in different directories and pass the html's location as a parameter. The program (shell example below) traverses the subdirectory "sub"
and its subdirectories to look for .html's, but only works when my perl file is in the same subdirectory "sub". If I put the Perl file
in the home directory, which is one step back from the subdirectory "sub", it doesn't work.
In the shell, if I type "perl project.pl ./sub" from my home directory, it says could not open ./sub/file1.html. No such file or directory. Yet the file does exist in that exact spot. file1.html is the first file it is trying to read.
If I change directories in the shell to that subdirectory and move the .pl file there and then say in the shell: "perl project.pl ./" everything is ok.
To search the directories, I have been using the File::Find concept which I found here: How to traverse all the files in a directory; if it has subdirectories, I want to traverse files in subdirectories too Find::File to search a directory of a list of files
#!/usr/bin/perl -w
use strict;
use warnings;
use File::Find;
find( \&directories, $ARGV[0]);
sub directories {
$_ = $File::Find::name;
if(/.*\.html$/){#only read file on local drive if it is an .html
my $file = $_;
open my $info, $file or die "Could not open $file: $!";
while(my $line = <$info>) {
#perform operations on file
}
close $info;
}
return;
}
Upvotes: 3
Views: 488
Reputation: 46245
From the File::Find documentation:
For each file or directory found, it calls the &wanted subroutine. (See below for details on how to use the &wanted function). Additionally, for each directory found, it will chdir() into that directory and continue the search, invoking the &wanted function on each file or subdirectory in the directory.
(emphasis mine)
The reason it's not finding ./sub/file1.html
is because, when open
is called, File::Find has already chdir
ed you into ./sub/
. You should be able to open the file as just file1.html
.
Upvotes: 1
Reputation: 54381
In the documentation of File::Find it says:
You are chdir()'d to $File::Find::dir when the function is called, unless no_chdir was specified. Note that when changing to directories is in effect the root directory (/) is a somewhat special case inasmuch as the concatenation of $File::Find::dir, '/' and $_ is not literally equal to $File::Find::name.
So you actually are at ~/sub
already. Only use the filename, which is $_
. You do not need to overwrite it. Remove the line:
$_ = $File::Find::name;
Upvotes: 3
Reputation: 62236
find
changes directory automatically so that $File::Find::name
is no longer relative to the current directory.
You can delete this line to get it to work:
$_ = $File::Find::name;
See also File::Find no_chdir
.
Upvotes: 1