Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Stat and file size

by Ormus (Initiate)
on Jul 28, 2012 at 19:35 UTC ( [id://984226]=perlquestion: print w/replies, xml ) Need Help??

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

New to Perl, and using 5.8.8 I am trying to scan all the files in a folder and determine which ones have a file size greater then zero. Eventually will delete all files in that folder using unlink that have a file size greater then zero. I wrote this script that seems to be "should" work, but when I print, it prints the files that have a file size of zero as well (prints all the files).
$testfolder = '.\test'; $testfolder =~ s/\//\\/g; opendir Sdir, $testfolder; @files = readdir(Sdir); undef @newfiles; foreach $file (@files) { $full_pathname = $testfolder . "/" . $file; my ($filesize) = (stat $full_pathname)[7]; if ($filesize > 0) { $full_pathname = $testfolder . "/" . $file; if (-e $full_pathname) { @newfiles = (@newfiles,$file1); } } } foreach $file1 (@files) { print "$file1\n"; }

Replies are listed 'Best First'.
Re: Stat and file size
by shmem (Chancellor) on Jul 28, 2012 at 19:43 UTC
    but when I print, it prints the files that have a file size of zero as well (prints all the files).

    Of course it does print all files, since you print the elements of @files, not @newfiles.

    But then, the array @newfiles would contain zero length elements, since you add $file1 to the array in a convoluted way (see push), which at that point is undefined.

    Adding

    use strict; use warnings;

    to the top of this code snippet's scope would catch that (and force you to declare the variables you use). See strict, warnings

Re: Stat and file size
by Kenosis (Priest) on Jul 28, 2012 at 19:46 UTC

    Perhaps the following -size File Test Operator and grep on a glob will work for you:

    my @nonZeroSizeFiles = grep -s, <*>;

    And in case you'd like to find zero-size files

    my @zeroSizeFiles = grep !-s, <*>;

    Hope this helps!

      And in case you'd like to find zero-size files

      my @zeroSizeFiles = grep !-s, <*>;
      my @zeroSizeFiles = grep -z, <*>;
      Not sure how I would use that Kenosis, sorry

        Here's one way to use it:

        use strict; use warnings; my $dir = './'; my @nonZeroLengthFiles = grep -s, <$dir*>; print "$_\n" for @nonZeroLengthFiles;

        This will print a list of all zero-length files in $dir.

Re: Stat and file size
by tobyink (Canon) on Jul 28, 2012 at 20:24 UTC
    # Delete non-zero length-files in "/tmp". unlink for grep -s, </tmp/*>;
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Stat and file size
by Ormus (Initiate) on Jul 28, 2012 at 19:59 UTC
    I did not see how the Push link helps, sorry! How would you write it? Thanks
      I got it working...thanks.
      $testfolder = '.\test'; $test =~ s/\//\\/g; opendir Sdir, $testfolder; @files = readdir(Sdir); undef @newfiles; foreach $file (@files) { $full_pathname = $testfolder . "/" . $file; my ($filesize) = (stat $full_pathname)[7]; if ($filesize > 0) { $full_pathname = $testfolder . "/" . $file; if (-e $full_pathname) { @newfiles = (@newfiles,$file); } } } foreach $file (@newfiles) { print "$file\n"; }

        I would write this a little differently to guard against a directory that has lots of files. The below example iterates over the directory handle instead of adding the directory filenames to an array. I also added more error checking to give a tighter example.

        use strict; use warnings; my $testfolder = './test'; my @newfiles; if ( opendir(my $dir, $testfolder) ) { while ( my $file = readdir($dir) ) { # skip parent and current directories next if ($file eq '.' || $file eq '..'); # skip directories next if (-d $file); # create the fullpath my $full_pathname = $testfolder . "/" . $file; next unless (-e $full_pathname); # get the filesize my $filesize = -s $full_pathname; # push the non-zero sized file to the new file array if ($filesize) { push(@newfiles,$file); } } closedir($dir); } else { die "[Error] UNABLE TO OPEN DIRECTORY: [$!]"; } foreach my $file (@newfiles) { print "$file\n"; }

        Great, Ormus!

      Push is used like so:

      push @array, $var1, $var2, $var3, ...;

      Therefore, @newfiles = (@newfiles,$file); should be push @newfiles, $file;

        Thanks Anonymous Monk

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (9)
As of 2024-04-18 11:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found