Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 742
  • Last Modified:

make an array of a directory tree/files paths in perl

I am looking (without installing extra packages) to get an array to have a directory structure  of a bunch of folders then go through each folder and list the files, (and also know the directory its in)

Take the following file paths (starting from 'My Photos' for instance):

/home/tim/my photos/
/home/tim/my photos/journey/1.jpg
/home/tim/my photos/journey/2.jpg
/home/tim/my photos/journey/3.jpg
/home/tim/my photos/birthday/1.jpg
/home/tim/my photos/birthday/2.jpg
/home/tim/my photos/birthday/3.jpg

I would like to find the code that makes me an array of the directorys (recursively) in a given path - in the above example I would like @dirs = ("/home/tim/my photos/journey/" , "/home/tim/my photos/birthday/")

Then I want to get the full file paths into another array...  so @files = ("/home/tim/my photos/journey/1.jpg","/home/tim/my photos/journey/2.jpg", "/home/tim/my photos/journey/3.jpg"....

I know this should be easy but I can't find a straightforward approach, I don't wish to have it rely on other packages as it has to run from different web servers which won't let me install extra packages from CPAN etc.
0
timbo007
Asked:
timbo007
  • 2
  • 2
2 Solutions
 
mrjoltcolaCommented:
Hope this gets you startred.
#!/usr/bin/perl
 
use strict;
use File::Find;
my @files;
 
find( \&handleFile, '/home' );
 
# Print out sorted list if desired...
#print sort @files;
 
 
sub handleFile() {
 
   if(-d) {
      # Print each file and store into list as we go
      print "$File::Find::name\n";
      push @files, $File::Find::name;
   }
 
}

Open in new window

0
 
WeiXiCommented:
This works without any extra package. It is rather straight-forward, anyway.
my $root = '/home/tim/my photos';
my @dirs;
my @jpgs;
 
sub recurse {
    my $base = shift;
    push @dirs, $base;
    opendir(my $DIR, $base) || die "can't opendir $base: $!";
    my @dircontents = readdir $DIR;
    closedir $DIR;
    push @jpgs, grep { /\.je?pg$/i && -f $_ } map {"$base/$_"} @dircontents;
    recurse("$base/$_") foreach grep { /[^.]/ && -d "$base/$_" } @dircontents;
}
 
recurse $root;

Open in new window

0
 
timbo007Author Commented:
Both answers worked for me, but the first answer by mrjoltcola was easier to implement into my own program. However the second one doesn't use any other packages at all! luckily File::find seems to be installed by default :)

I don't quite understand whats going on the last part of the recurse sub (at row 12) on the second example as that seems outside what I know, do you have the time to elaborate on what it means for me ?

cheers!!
    recurse("$base/$_") foreach grep { /[^.]/ && -d "$base/$_" } @dircontents;

Open in new window

0
 
WeiXiCommented:
/[^.]/
Match only strings with at least one character that's not a dot. This is to prevent an infinite loop into directory '.'

-d "$base/$_"
Returns true if "$base/$_" is a directory, other wise false.

grep { /[^.]/ && -d "$base/$_" } @dircontents
Filter all entries in the current directory that are directores themselves, but not '.' and '..'

foreach grep { /[^.]/ && -d "$base/$_" } @dircontents
Iterate over all those filtered directories...

recurse("$base/$_") foreach grep { /[^.]/ && -d "$base/$_" } @dircontents;
...and iteratively call the recurse function with the filtered directories as arguments.
0
 
mrjoltcolaCommented:
Curious why you graded with a B since you did not ask for clarification before closing the question?
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now