oryann9 wrote:

Randal L. Schwartz - Stonehenge Consulting Services, Inc.

You're misusing it.  Set it within the wanted() routine when you're
looking at a directory that you don't want to descend.  It'll be
cleared to 0 before calling wanted(), so setting it before calling
find() is completely useless.

Will anyone help me with this issue? These three lines of code work,
but work in a way that I am not expecting. When I tell this module to
set no_chdir to 1 it should NOT descend directories yet it does.

no_chdir does not do what you seem to think it does.  No matter what the
value of no_chdir is File::Find::find will *always* descend directories.

perldoc File::Find
[ SNIP ]
    "no_chdir"
        Does not "chdir()" to each directory as it recurses.

Note that it still recurses, it just does not chdir().

You want to set the $File::Find::prune variable to true from *inside* File::Find::find's wanted subroutine. But of course you can't do that with File::Find::Closures unless you define your own closure.


Am  I supposed to have a wanted routine other than whats below? Below
are  the 3 lines I have tried and below that is the entire script.

thank you!

1) File::Find::find ( { wanted => $wanted, no_chdir => $File::Find::no_chdir }, 
$fs ) ;

2) File::Find::find ( { wanted => $wanted, no_chdir => +shift }, $fs ) ;

3) File::Find::find ( { wanted => $wanted, no_chdir => $File::Find::no_chdir = 
shift}, $fs


#!/usr/bin/perl

use strict ;
use warnings ;
use File::Find ;
use File::Find::Closures qw(find_by_min_size) ;

##-- Begin Format Code --##

my ($key,$user,$grp,$mod,$sz) ;

format STDOUT_TOP =
Page @<<<
$%

FileName                                                                   
Owner    GroupOwner   LastMo
ate   Size
=========                                                                  
=======  ===========  ======
====  =====
.

format STDOUT =
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<   @<<<<<<< @<<<<<<    
  @<<<<<
<<<   @##.###
$key,                                                                      
$user,   $grp,        date_m

That should be $mod instead of 'date_m'.

,     $sz
.

##-- End Format Code --##

sub date_me {

        my $mod = shift @_ ;
        my ($seconds, $minutes, $hours, $day_of_month, $month, $year,
        undef, undef, undef) = localtime($mod) ;

        #printf("%02d:%02d:%02d-%02d/%02d/%04d",
        ( $hours, $minutes, $seconds, $month+1, $day_of_month, $year+1900 ) ;
}

my $log = qq(/var/adm/find_hog.log) ;
my $logg ;
open ($logg, '>>', $log) or warn "file '$logg' was not opened $!" ;

You are just using warn() which means that you want to print to $log whether the file was opened or not?


START:
print qq (\nPlease enter filesystem name in the form of /fsname or / just for 
root\n) ;
print "\n";
chomp (my $fs = <>) ;

if ( $fs eq "/" ) { # only if the root directory, do not descend.
    find_me ( $fs, 0 );
}
elsif ( $fs =~ m|^/\w+|i ) { ## matches /var
    find_me ( $fs, 1 );
}
elsif ( $fs =~ m|^[/.\w+]|i ) {  ## matches /.ssh

That pattern will never match '/.ssh'. It will match a single character at the beginning of the line, one of either '/', '.', '+' or a member of the character class \w. If you want it to match /.ssh then try m|^/\.\w+|.

Or better yet, combine the two previous:

elsif ( $fs =~ m|^/\.?\w+|i ) {


    find_me ( $fs, 1 );
}
else {
     warn "\nFilesystem name does not match expression.\nPlease contact Unix on 
call and or try again\n
     goto START;
}

It is poor form to use goto:

START:  {
print "\nPlease enter filesystem name in the form of /fsname or / just for root\n\n";
    chomp( my $fs = <> );

    if ( $fs eq '/' ) {    # only if the root directory, do not descend.
        find_me( $fs, 0 );
        }
    elsif ( $fs =~ m|^/\.?\w+| ) {    ## matches /var or /.ssh
        find_me( $fs, 1 );
        }
    else {
warn "\nFilesystem name does not match expression.\nPlease contact Unix on call and or try again\n";
        redo START;
        }
    }


my ( @sorted_large_files, @large_files ) ;

sub find_me {
    use Data::Dumper;
    my $fs = shift;
    #local $File::Find::prune = shift; ##-- localize prune to just this block 
--##
    #my @directory = ($fs) ;
    use constant MAX_SIZE => (25*1024*1024) ;
    use constant DIVISOR  => (1024) ;
    my ( $wanted, $list ) = find_by_min_size ( MAX_SIZE ) ;
    File::Find::find ( { wanted => $wanted, no_chdir => +shift }, $fs ) ;
    @large_files = $list->() ;


    @sorted_large_files =
        sort { -s $b <=> -s $a }
    @large_files ;

You are stat()ing the files more than you need to. You can use a Schwartzian Transform to minimize IO:

    @sorted_large_files =
        map $_->[ 0 ],
        sort { $b->[ 1 ] <=> $a->[ 1 ] }
        map [ $_, -s ],
        $list->();


} ##-- End sub --##

    if (@sorted_large_files) {

You don't need this section of code inside an if block:

unless ( @sorted_large_files ) {
    warn "\nNo file(s) over twenty-five Mb found in $fs\n";
    exit 0;
    }


        my %meta ;
        for my $file (@sorted_large_files) {
            $meta{$file} = {
                     'uid' => (stat($file))[4],
                     'gid' => (stat($file))[5],
                     'sz'  => (stat($file))[7],
                     'mod' => (stat($file))[9],
            } ;

You can simplify that (and only call stat() once) with a hash slice:

my %meta;
for my $file ( @sorted_large_files ) {
@{ $meta{ $file } }{ qw/uid gid sz mod/ } = ( stat $file )[ 4, 5, 7, 9 ];
    }


        } ## END FOR ##

        for $key ( keys %meta ) {
            $user = getpwuid $meta{$key}->{'uid'} ;
            $grp  = getgrgid $meta{$key}->{'gid'} ;
            $mod  = $meta{$key}{'mod'} ;
            $sz   = $meta{$key}{'sz'} / DIVISOR / DIVISOR ;
            #print "\n$key => $user\t$grp\t\t" ;
            #date_me($mod) ;
            #printf("\t%0.3f Mb\n",$sz) ;
            write ;
        }

    } ##-- End @sorted_large_files if --##

    else {
        warn "\nNo file(s) over twenty-five Mb found in $fs\n" ;
        exit 0 ;
    }

    END {
        close ($logg) or warn "Log '$logg' failed to close $!" ;
    }

An END{} block will execute at the end of the program no matter where it is physically placed in the file so why not put it closer to where the file is opened.



John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order.                            -- Larry Wall

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to