in reply to Re: Directory listing
in thread Directory listing

Awesome, that is a good start... now if I get rid of the input and just have
qw(usr local farms * *), "*$corp*"
Will it do a recursive search through log, input, save, failed, etc? or will I have to make a seperate subroutine for each of those paths?

Also, would you be willing to do a small breakdown of what each line is actually doing (only the one's you changed, I should hope I know what the ones I wrote were doing) so I'm not just taking prefabbed code... I'd like to relearn this (I never really got far with perl in the first place, so I guess learn would be a better word than relearn)

Also, with glob, is there some way that I can get the date, time, and bytecount of the files being returned?

Replies are listed 'Best First'.
Re^3: Directory listing
by Tanktalus (Canon) on Jan 17, 2005 at 14:59 UTC

    Here's some comments in-line:

    # supersearch this one - short version: it detects most common coding +errors. # always use it. use strict; sub lsForCorp { my $corp = $_[0]; # File::Spec allows you to create a directory structure in # a platform-independant manner. Not a big deal to you since # this probably only runs on unix anyway, but all my code # has to run on both unix and Windows, so it's just a # habit. require File::Spec; my $path = File::Spec->catfile( # this reconstructs the path - if you print $path, you'll # see exactly the path you were using - again, no big deal # if portability is unimportant (and "/usr/local" is not # really portable either ;->) File::Spec->rootdir(), qw(usr local farms * * input), "*$cor +p*" ); # let glob do all the work rather than ls. Besides, ls # calls the same thing as glob under the covers, more or # less. (Technically, it's the shell.) my @farms = glob($path); foreach my $farm (@farms) { # no if statement since the glob already only gets files that match # *$corp*, which is the glob way of saying /\Q$corp/. print $farm, "\n"; } # end of foreach statement } #end of lsForCorp subroutine #------------------- End Subroutines ---------------------# print "What corp are you looking for? " ; # chomp it to remove the trailing newline. chomp(my $whatWeWant = <STDIN>); # & doesn't do what you think it does - avoid it unless you # actually mean to do what it does. lsForCorp($whatWeWant);

    If you want to search more than just "input", you want to search all directories at that level, you just change "input" to "*", and it'll handle that: /usr/local/farms/*/*/*/*$corp*. As long as everything is at the same depth in the directory tree, this works fine. If you're looking for files at different depths, you'll need to use File::Find or something similar.

    As for getting the date/time/bytecount, you'll need to use the -X functions and/or stat or File::stat. e.g.:

    use File::stat; # ... my $s = stat($farm); printf "%s: Age [%s], size [%d]\n", $farm, $s->mtime(), $s->size();

      Alright, I'm trying to get the date to be human readable... I figured the best thing for this is Date::Manip, however, I can't seem to get the filestat information into the datemanip...
      foreach my $farm (@farms) { my $s = stat($farm); printf "%s: Age [%s], size [%d]\n", $farm, &ParseDateString("epoc +h $s->mtime()"), $s->size(); } # end of foreach statement
      I've tried a couple things, but nothing I try seems to work...

      here's the entire script so far:

      #!/usr/bin/perl use strict; use File::stat; use Date::Manip; # This is a program that is intended to allow FEP operators # a tool that will facilitate in monitoring incoming transmissions # and preprocessor logs. #------------------- Define Subroutines ------------------# # # # Main is a subroutine simply written for flow control sub Main { my $corp = $_[0]; print "Input:\n"; farmInput($corp,'input'); } # end Main # farmInput does a wildcard search of all /usr/local/farm/*/*/input fo +lders # looking for the <STDIN> corp number and printing those files to scre +en. sub farmInput { my $corp = $_[0]; my $finalPath = $_[1]; my $path = "/usr/local/farm/*/*/$finalPath/*$corp*"; my @farms = glob($path); foreach my $farm (@farms) { my $s = stat($farm); printf "%s: Age [%s], size [%d]\n", $farm, &ParseDateString("epoc +h $s->mtime()"), $s->size(); } # end of foreach statement } # end farmInput #------------------- End Subroutines ---------------------# print "What corp are you looking for? " ; chomp(my $whatWeWant = <STDIN>); Main($whatWeWant);
      I'm trying to streamline it as I go, I know that in the farmInput subrouting I could put the $corp and $finalPath variables on the same line, just haven't gotten to that yet... I'd like my code to be as small and clean as possible... but it needs to work first! ;o)

        Didn't quite convert directly ;-) I personally prefer the OO interfaces, so instead of using stat directly, I used File::stat instead. So the missing piece is to add a use File::stat (and use "my $s = stat(...)"), or to use @fileStat to get the fields. My problem with @fileStat is that I never remember which field is which ;-)

        use File::stat; foreach my $farm (@farms) { my $s = stat($farm); printf "%s: Age [%s], size [%d]\n", $farm, ParseDateString("epoch +$s->mtime()"), $s->size(); } # end of foreach statement

        I do have a question - why do you keep putting the &'s in front of your function calls (such as ParseDateString)?