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

Hi Monks,
I am trying to get the size of any *.txt file found in a specific(s) location(s) but I am loosing the values after the first file gets read, any help, I just can't see it anymore.
#Lets assume that the locations will be passed like: c:/progra~1/apache~1/apache2/htdocs/a_error1 c:/progra~1/apache~1/apache2/htdocs/a_error2 into an array @local_list; #Open directory and search for *.TXT files my(@dircontent, $filesize, $file); for my $path(@local_list) { opendir my $dirh,$path or die "Can't open $path"; push (@dircontent,grep { /\.txt$/ } readdir($dirh)); closedir($dirh) or die "Can't close $path"; } #After finding all the text files I need to get the file names and it' +s size and print it out, but I am loosing value after the first file, + why? my $list_count=-1; foreach my $file (@dircontent) { $list_count++; $filesize = -s $file; print "<br><b>L123 - $list_count - The file name: <a href=../../$l +ocal_list[$list_count]/$file>$file</a></b> is <font color=red>$filesi +ze</font> bytes long.<br>\n\n"; #exit; }

Thanks!

Replies are listed 'Best First'.
Re: File Size in Directory
by physi (Friar) on Feb 14, 2006 at 19:17 UTC
    You have to save the whole filename, including the path in your grep construct.
    push (@dircontent, map { $_="$path/$_"; $_;} grep { /\.txt$/ } readdir +($dirh));
    Maybe the '/' must be an '\' for windows, you have to try it

    Cheers physi

    -----------------------------------
    --the good, the bad and the physi--
    -----------------------------------
    
      It will work like that!
Re: File Size in Directory
by davidrw (Prior) on Feb 14, 2006 at 19:25 UTC
    Problem is $local_list[$list_count] in your print line ... @local_list only has 2 elements, but $list_count is in the range 0 ... $#dircount ... Root issue is that you need to keep track of what directory you found each file in ..

    One way to solve this is just do it all at once:
    foreach my $path ( @local_list ){ opendir my $dirh,$path or die "Can't open $path"; my @files = grep { /\.txt$/ } readdir($dirh); closedir($dirh) or die "Can't close $path"; foreach my $i (0..$#files){ my $file = $files[$i]; printf( '<br><b>L123 - %d - The file name: <a href="../../%s/%s">%s</a>< +/b> is <font color=red>%d</font> bytes long.<br>' . "\n\n", $i, $path, $file, $file, -s $file ; } }
    Otherwise you need a data structure other than just @dircontent ...

    Also of interest might be File::Find and File::Find::Rule ...

    Update: a File::Find::Rule (and File::Basename) solution:
    use File::Find::Rule; use File::Basename; my @files = File::Find::Rule->file() ->name( '*.txt' ) ->maxdepth(1) ->in( @local_list ) ; foreach my $i (0..$#files){ my $file = $files[$i]; printf '<br><b>L123 - %d - The file name: <a href="../../%s">%s</a></b> + is <font color=red>%d</font> bytes long.<br>' . "\n\n", $i, $file, basename($file), -s $file, ; }
Re: File Size in Directory
by holli (Abbot) on Feb 14, 2006 at 19:52 UTC
    I'm currently writing a module named FileSystemObjects::Directoy. It's Beta but most features seem to be stable. I have not put it to CPAN yet, because I discovered Path::Class which has similar features and want to examine it's code before. Anyway, with FileSystemObjects::Directoy you could write your code like
    use FileSystemObjects::Directory; #... for ( @path ) { my $dir = FileSystemObjects::Directory->new ($_); for ( $dir->files (mask => '*.txt') ) { print $_->name, " / ", $_->size, "\n"; }
    I can post it's code here if you volunteer to test it.


    holli, /regexed monk/
Re: File Size in Directory
by smokemachine (Hermit) on Feb 14, 2006 at 19:29 UTC
    perl -e 'print "<br><b>L123 - ".++$count." - The file name: <a href=.. +/../$_>$_</a></b> is <font color=red>".(-s)."</font> bytes long.<br>\ +n\n"while <*.txt>'
Re: File Size in Directory
by ayrnieu (Beadle) on Feb 15, 2006 at 07:06 UTC
    My cents, untested, before I crash.
    sub file_sizes { my $match = shift; my %sizes; for (@_) { for (glob("$_/$match")) { $sizes{$_} = -s $_ } } %sizes } my %txts = file_sizes("*.txt", qw,/home/*/docs /usr/share/doc/txt,);