bizactuator has asked for the wisdom of the Perl Monks concerning the following question:

I have some software that has thousands of files. apparently some files are missing.

So I uploaded a fresh copy and put it in a directory, lets say the name of it is:

/home/path/public_html/software
and everything is normally here:

/home/path/public_html/

so I want to open the software directory and read the name of every file including the path to it, including recursively going into directories...

here is what I came up with...
but it is only reading the files and directory names, it is not going deep into the directories...

my $_FirstDir = "/home/path/public_html/software"; my $_secondDir = "/home/path/public_html"; opendir (DIR, $_FirstDir) or die "Couldn't open $_FirstDir: $!\n"; my @DirList = readdir(DIR); closedir(DIR); my $_filesNotThere = ""; my $_numMissing = 0; my $_filesThere = 0; foreach my $DirFile (@DirList) { if (-e "$_secondDir/$DirFile") { $_filesThere++; } else { $_filesNotThere .= "$_secondDir/$DirFile\n"; $_numMissing++; } }

Then I go show the number of missing files, with the number of files that are there... so I can see the difference... and I then open and print the list of those missing to a text file.

It works, except does not go deep into directories... so is there a way to have it go to each directory and back up then down to the next and back up, then the next, etc?

I'd greatly appreciate the advice on what I did wrong.

-Rich

Replies are listed 'Best First'.
Re: Opening Directory and reading all file names and directory names
by choroba (Cardinal) on Feb 17, 2019 at 17:38 UTC
    You can implement it yourself, you just need to separate the repeated logic into a subroutine and call the subroutine recursively from itself when a directory is encountered.

    Another possibility would be to use File::Find to walk the directories for you. $File::Find::name will contains the relative path to each of the files/directories.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: Opening Directory and reading all file names and directory names
by 1nickt (Canon) on Feb 18, 2019 at 03:43 UTC

    "what I did wrong"

    The learned choroba answered that question; your program lacked recursion. I recommend using Path::Iterator::Rule for this kind of recursive file-finding exercise. I like its compact and clear syntax, as shown in this simple demo:

    use strict; use warnings; use feature 'say'; use Path::Iterator::Rule; my $dir = '1230046/public_html/software'; my $_numMissing = 0; my $_filesThere = 0; my $r = Path::Iterator::Rule->new->file->exists->and(sub { my $wanted = $_[0] =~ s!software/!!r; -e $wanted ? $_filesThere++ : $_numMissing++ && say "$wanted is mi +ssing"; })->all($dir); say " Found: $_filesThere"; say "Missing: $_numMissing"; __END__

    Test directory structure:

    Output:

    $ perl 1230046.pl 1230046/public_html/foo/42.txt is missing 1230046/public_html/foo/43.txt is missing 1230046/public_html/quux/42.txt is missing 1230046/public_html/foo/baz/42.txt is missing 1230046/public_html/foo/baz/43.txt is missing Found: 6 Missing: 6

    Hope this helps!


    The way forward always starts with a minimal test.