?
Solved

keeping subdirectory files in order

Posted on 2003-02-24
10
Medium Priority
?
368 Views
Last Modified: 2012-06-27
I am traversing a directory with all its subdirectories and I need to keep all the filenames grouped by directories, starting with the root, then going depth-first.  This does not automatically happen because some filenames in the root directory, for example, may alphabetically precede the subdirectories. In order to fix this, I was thinking of adding a prefix to each file, so if it's in the root, its prefix would be 001, the next folder would be 002, etc. So basically, I want it to look something like this:  "001C:\Perl\Test\Image.tif"
                      "002C:\Perl\Test\SubDir\Image.tif"
Any ideas on how to add this prefix (which I will later remove) or another way to keep the directories in order?
Thanks
 
0
Comment
Question by:njprov
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
10 Comments
 
LVL 26

Accepted Solution

by:
wilcoxon earned 150 total points
ID: 8013262
One simple way is to use nested hashes.  The directories:

C:\Perl\Test\Image.tif
C:\Perl\Test\SubDir\Image.tif

Would end up being stored as:

$hash{C}{Perl}{Test}{Image.tif} = 1 (or some other value)
$hash{C}{Perl}{Test}{SubDir}{Image.tif} = 1

-or-

$hash{C}{Perl}{Test}{_files} = ['Image.tif', etc]
$hash{C}{Perl}{Test}{SubDir}{_files} = ['Image.tif', etc]

Or I'm sure you could come up with other some other method.
You could also keep an array of arrays for quick depth counts.

$depth[2] = ['C:\Perl\Test', etc]
$depth[3] = ['C:\Perl\Test\SubDir', etc]
0
 
LVL 5

Expert Comment

by:PC_User321
ID: 8015055
use File::Find;
$directory = ".";   # (or whatever)

sub wanted
{
    print "Found $File::Find::dir   $_\n"  unless (-d);
}

find(\&wanted, $directory);
0
 
LVL 26

Expert Comment

by:wilcoxon
ID: 8016421
I'm pretty sure File::Find returns things in physical storage order within the directory, doesn't it?  Physical storage order is usually not alphabetically ordered (unless you're on Windows with FAT32 and just ran Norton SpeedDisk or similar).

If that is the case, then the files returned by File::Find will not be ordered (one of niprov's requirements).
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:njprov
ID: 8017663
Thanks, these are good ideas.  As far as the File::Find, I can't seem to use it. In fact, I can't get past the "use File::Find;" line, I get:

File/Find.pm in @INC at test.pl line 1

Is this a version problem, am I missing some libraries? I'm a Perl beginner so please bear with me. Thanks!
0
 

Author Comment

by:njprov
ID: 8017701
Sorry, that should be:

Can't locate File/Find.pm in @INC at test.pl line 1

0
 
LVL 26

Expert Comment

by:wilcoxon
ID: 8018419
Hmm.  What version of perl are you using (perl -V should tell you)?

File::Find should be part of the core modules.  I'm not sure with what version it was added though.
0
 

Author Comment

by:njprov
ID: 8018812
it's version 5.001
0
 
LVL 26

Expert Comment

by:wilcoxon
ID: 8018960
Ah.  That is a very old version of perl.  I am fairly sure File::Find was not part of the core at that point.

If you have the option, you might want to seriously consider upgrading to a more recent perl - 5.005_03 (the last before 5.6), 5.6.1 (5.6.0 was buggy), or 5.8.0 are good candidates.
0
 

Author Comment

by:njprov
ID: 8019110
it's version 5.001
0
 

Author Comment

by:njprov
ID: 8019440
Thank you for your help. I don't know why we are using an old version, I'll find out about that. Meanwhile, I wrote my own function which takes care of the alphabetical problem by processing each file in a directory first, before going into the next directory. Here is the code, in case someone runs into a similar problem.

my($root) = "C:\\Perl\\Test";
DoDir($root);

sub DoDir
{
   my($dir) = shift;
   my($file);
   opendir(DIR, $dir) || die "Unable to open $dir :$!";
   my(@files) = grep {!/^\.\.?$/ } readdir(DIR);
   closedir(DIR);
   foreach (@files)
   {
      if (-f ($file = "$dir\\$_"))
      {
      #process the file here  
      print "Found a file: $file\n";
      }
   }
   foreach (@files)
   {
      if (-d ($file = "$dir\\$_"))
      {
         print "Found a directory: $file\n";
         DoDir($file);
      }

   }
}
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A year or so back I was asked to have a play with MongoDB; within half an hour I had downloaded (http://www.mongodb.org/downloads),  installed and started the daemon, and had a console window open. After an hour or two of playing at the command …
There are many situations when we need to display the data in sorted order. For example: Student details by name or by rank or by total marks etc. If you are working on data driven based projects then you will use sorting techniques very frequently.…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Six Sigma Control Plans
Suggested Courses

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question