in reply to Re^2: Directory listing
in thread Directory listing

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();

Replies are listed 'Best First'.
Re^4: Directory listing
by FireyIce01 (Novice) on Jan 18, 2005 at 04:37 UTC
    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)?

        edit: found the answer I was looking for -
        http://www.perlmonks.org/index.pl?node_id=422895

        don't know, what do the &'s do? all the example code I can find uses them, so I thought it was the proper function call...

        the @fileStat was actually remnants of a previous attempt at figuring out how to get the date extracted that I had failed to rever to $s when I went back... explained why it was blowing up... I have the use File::stat; at the very top of the code right after the #!/usr/bin/perl... my problem is that with the code as it is right now:

        sub farmInput { my($corp, $finalPath) = ($_[0], $_[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("epoch + $s->mtime()"), $s->size(); # printf "%s: Age [%s], size [%d]\n", $farm, $s->mtime(), $s->size( +); } # end of foreach statement } # end farmInput
        it doesn't display anything in between the after date, but when I use the other line (the one commented out in this code) it gives me the seconds since epoch...

        sooo... when I use this:

        printf "%s: Age [%s], size [%d]\n", $farm, ParseDateString("epoch + $s->mtime()"), $s->size();
        I get this:
        /usr/local/farm/vrsn/verisignx/input/75192.hosoft.01162005.A.bctl.e.le +t.dat.Z: Age [], size [2069] /usr/local/farm/vrsn/verisignx/input/75192.hosoft.01162005.A.bills.let +.dat.Z: Age [], size [266666425] /usr/local/farm/vrsn/verisignx/input/75192.hosoft.01162005.A.billvldt. +let.dat.Z: Age [], size [72] /usr/local/farm/vrsn/verisignx/input/75192.hosoft.01162005.A.bmsg.e.le +t.dat.Z: Age [], size [2428] /usr/local/farm/vrsn/verisignx/input/75192.hosoft.01162005.A.brels.let +.dat.Z: Age [], size [8] /usr/local/farm/vrsn/verisignx/input/75192.hosoft.01162005.A.callfile. +call.dat.Z: Age [], size [126369639]
        and then when I use this:
        printf "%s: Age [%s], size [%d]\n", $farm, $s->mtime(), $s->size() +;
        I get this
        /usr/local/farm/vrsn/verisignx/input/75192.hosoft.01162005.A.bctl.e.le +t.dat.Z: Age [1106013532], size [2069] /usr/local/farm/vrsn/verisignx/input/75192.hosoft.01162005.A.bills.let +.dat.Z: Age [1106018445], size [266666425] /usr/local/farm/vrsn/verisignx/input/75192.hosoft.01162005.A.billvldt. +let.dat.Z: Age [1106018446], size [72] /usr/local/farm/vrsn/verisignx/input/75192.hosoft.01162005.A.bmsg.e.le +t.dat.Z: Age [1106013532], size [2428] /usr/local/farm/vrsn/verisignx/input/75192.hosoft.01162005.A.brels.let +.dat.Z: Age [1106013532], size [8] /usr/local/farm/vrsn/verisignx/input/75192.hosoft.01162005.A.callfile. +call.dat.Z: Age [1106020765], size [126369639]
        Again, here is the entire program:
        #!/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, $finalPath) = ($_[0], $_[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("epoch + $s->mtime()"), $s->size(); # printf "%s: Age [%s], size [%d]\n", $farm, $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);