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

I have the following in a text file.
01000103.drw 01020028.prt 01040167g.prt 01050051.asm 01070119.drw
etc...
I put it in a hash as follows:

open(FILE, "<dup01032004.txt"); while (<FILE>) { $hash{$.} = $_; } close(FILE); foreach (keys %hash) { print("$hash{$_}"); }
Now I need to continue with the code and have it take the hash and search through subdirectories that match those numbers..How do I continue? I will then need to move those numbers into an archive directory once I find a match.
Thanks

Updated Steve_p - added code tags

Replies are listed 'Best First'.
Re: subdirectory question
by NetWallah (Canon) on Jan 03, 2005 at 06:13 UTC
    Your approach to the problem, as well as the problem description raises too many questions to provide a complete answer. Anyway , here is an attempt:

    • Why are you using a hash to store what seems like a simple list of file names? I would use a simple @array.
    • Searching directories/subdirectories is best done by a module like File::Find.
    • use the perl grep function to search an array.
    • use the perl rename function to move files.

        ..."I don't know what the facts are but somebody's certainly going to sit down with him and find out what he knows that they may not know, and make sure he knows what they know that he may not know, and that's a good thing. I think it's a very constructive exchange," --Donald Rumsfeld

      Why are you using a hash to store what seems like a simple list of file names? I would use a simple @array.

      use the perl grep function to search an array.

      Don't you see the contradiction in these two sentences? I'd use a hash, but with the names read into the keys, not the values. That way, you can easily check whether a filename is in the hash. For example,

      while(<>) { /(.*)/; $names{$1} = 1; } use File::Find (); File::Find::find sub { $names{$_} and -x and print $File::Find::name, "\n"; }, grep -e, split ":", $ENV{"PATH"};
      searches for binaries with the names given on ARGV.
        Clever code!

        I would have used chomp instead of "/(.*)/", and split on ";" for Windoze.

        Anyway, to respond to your question - I had not optimized my proposed solution to the extent you have, so I did not see the "contradiction". My proposal suggested storing the file names in an array, and "grep"ping it for each file.

        I would agree that your solution is faster. To optimize memory it even more, you could set "$names{$1}=undef", and use "exists $names{$_}" when querying.

            ..."I don't know what the facts are but somebody's certainly going to sit down with him and find out what he knows that they may not know, and make sure he knows what they know that he may not know, and that's a good thing. I think it's a very constructive exchange," --Donald Rumsfeld

Re: subdirectory question
by jbrugger (Parson) on Jan 03, 2005 at 06:13 UTC
    Not sure what you exactly want, but this might help you a bit further:

    #!/usr/bin/perl use Cwd; open(FILE, "<dup01032004.txt"); while (<FILE>) { $hash{$.} = $_; } close(FILE); foreach (keys %hash) { my ($num) = $hash{$_} =~ m/(.*)?\..*/; if (-d $num) { # ah! the folder exists! print("The folder $num exists! so make your killerapp do the work!!!\n"); chdir $num or die("Cannot change to directory\n"); print "Current folder = " . getcwd() . "\n"; #Now do your stuff in this folder here! chdir ".." or die("Cannot go back...\n"); print "Current folder = " . getcwd() . "\n"; } }
Re: subdirectory question
by dave_the_m (Monsignor) on Jan 03, 2005 at 10:34 UTC
    Hmmm, two almost identical questions by two posters within a short period of each other. Are some people looking for help with their homework ?

    Dave.