Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Check Directories for Files

by drodinthe559 (Monk)
on Nov 24, 2009 at 19:06 UTC ( [id://809171]=perlquestion: print w/replies, xml ) Need Help??

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

Monks: I need to check each of the below directories for any files. If there is a file, I need to move it to a temp directory. I would like to know if there is a more efficient way to check each directory. I'm thinking a loop of some sort, but there is a gap of numbers.
#!/usr/bin/perl -w use strict; use warnings; use File::Copy; if (-e "D:/DOWNLOAD/DISTRBTN/I01/B01/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B02/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B03/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B04/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B05/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B06/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B07/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B08/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B09/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B10/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B11/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B12/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B13/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B14/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B15/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B16/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B17/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B18/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B19/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B20/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B21/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B22/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B50/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B60/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B70/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B80/") { } if (-e "D:/DOWNLOAD/DISTRBTN/I01/B97/") { }

Replies are listed 'Best First'.
Re: Check Directories for Files
by almut (Canon) on Nov 24, 2009 at 19:40 UTC
    I'm thinking a loop of some sort, but there is a gap of numbers.

    You could still use a loop, e.g.

    for my $n (1..22,50,60,70,80,97) { my $path = sprintf "D:/DOWNLOAD/DISTRBTN/I01/B%02d/", $n; if (-e $path) { #... } }
Re: Check Directories for Files
by toolic (Bishop) on Nov 24, 2009 at 19:41 UTC
    This will find all files in the subdirectories of the Bxx dirs which you specified. This will not recurse below the Bxx dirs. File::Slurp
    use strict; use warnings; use File::Slurp qw(read_dir); my $path = 'D:/DOWNLOAD/DISTRBTN/I01/B'; my @dirs = map { sprintf "$path%02d/", $_ } 1..22, 50, 60, 70, 80, 97; for my $dir (@dirs) { my @files = grep { -f "$dir/$_" } read_dir($dir); # do something with files }
    If you really want all Bxx dirs, then @dirs could be simplified using glob.

    Update: added grep to just get files.

Re: Check Directories for Files
by halfcountplus (Hermit) on Nov 24, 2009 at 19:33 UTC
    Since these appear to be in a tree, you might want to investigate File::Find, which works recursively. You can use the callback to the find() to move the files found to wherever.
    find (\&checkfor, "D:/DOWNLOAD/DISTRBTN/I01/"); sub checkfor { if (-f $_) { print $File::Find::name."\n" }; }
    That will print out the full pathnames of all files in DISTRVTN/IO1 and all of it's subdirectories.
Re: Check Directories for Files
by Your Mother (Archbishop) on Nov 24, 2009 at 20:07 UTC

    Another approach. You should be able to see how you could recurse into sub-dirs with the same idea. Path::Class.

    use Path::Class (); my $dir = Path::Class::Dir->new("D:/DOWNLOAD/DISTRBTN/I01/"); for my $file ( grep { not $_->is_dir } $dir->children ) { print $file, $/; }
Re: Check Directories for Files
by baxy77bax (Deacon) on Nov 24, 2009 at 19:43 UTC
    hi,

    well Perl has got this two cool functions (among others:)) :

    opendir(); readdir(); so what you could do is: use strict; use warnings; use File::Copy; opendir (DIR,"./path") || die "$!"; # this opens the directory foreach my $i(readdir DIR){ next if (/\./g || grep{$_=~/$i/g}22..50); move("./path/$i", "/tmp/$i"); # if (-e "./path/$i"); } closedir DIR;
    that is it :)

    UPDATE:

    my bad, tollic is right, so basically what you do is check if the var in question is a regular file or not:

    next unless(-f "./path/$i" || !grep{$_=~/$i/g}22..50);
    sorry :)
      next if (/\./g);
      That will skip all files and sub-directories which contain a literal dot in the name, such as 'file.txt'. It will not skip any directories which do not have a dot, such as 'junk'.
Re: Check Directories for Files
by leocharre (Priest) on Nov 24, 2009 at 20:40 UTC
    Just use bash (I'm sorry, Richard! well, yes, bash or whatnot- but.. the real star here is;) Use gnu findutils
    for dir in $(find /rootdir/101/ -type d -name "B??"); do find $dir -type f -exec rm '{}' \; ; done; # or to move elsewhere # do find $dir -type f -exec mv '{}' /tmp/foundstuff/ \; ;
    If you know to expect the filesystem hierarchy you suggested- There's not even a need to play with the B?? dirs..
    $ find /rootdir/101/ -type f -exec mv '{}' /tmp/foundstuff/ \;
      Thank you all for your suggestions.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://809171]
Approved by zwon
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (6)
As of 2024-03-19 08:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found