File::Find::Rule for files younger than 24 hours

Discussion in 'Perl Misc' started by Arvin Portlock, Jan 24, 2006.

  1. I'm trying to use File::Find::Rule to get files modified in
    the last 24 hours. With the help of find2perl I got a plain
    File::Find to work just fine, but File::Find is pretty horrible
    so I'd prefer File::Find::Rule. This is on a Windows 2000
    system:

    My working File::Find version:

    use File::Find;
    my $rootdir = 'D:/MYDOCU~1/schema_validate';
    File::Find::find({wanted => \&since_yesterday}, $rootdir);

    sub since_yesterday {
    my ($dev,$ino,$mode,$nlink,$uid,$gid);

    (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
    (int(-M _) < 1)
    && print("$File::Find::name\n");
    }

    My not-working File::Find::Rule version:

    use File::Find::Rule;

    my $rootdir = 'D:/MYDOCU~1/schema_validate';

    my @files = File::Find::Rule->file()
    ->name( '*.pl' )
    ->mtime ("-1")
    ->in($rootdir);
    foreach my $file (@files) {
    print "$file\n";
    }

    I've actually tried a variety of things for the mtime() method
    but either get nothing or I get everything. It's not clear to
    me how to apply mtime() here.

    Arvin
    Arvin Portlock, Jan 24, 2006
    #1
    1. Advertising

  2. Arvin Portlock

    Paul Lalli Guest

    Arvin Portlock wrote:
    > I'm trying to use File::Find::Rule to get files modified in
    > the last 24 hours. With the help of find2perl I got a plain
    > File::Find to work just fine, but File::Find is pretty horrible
    > so I'd prefer File::Find::Rule. This is on a Windows 2000
    > system:
    >
    > My working File::Find version:
    >
    > use File::Find;
    > my $rootdir = 'D:/MYDOCU~1/schema_validate';
    > File::Find::find({wanted => \&since_yesterday}, $rootdir);
    >
    > sub since_yesterday {
    > my ($dev,$ino,$mode,$nlink,$uid,$gid);
    >
    > (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
    > (int(-M _) < 1)
    > && print("$File::Find::name\n");
    > }


    fwiw, you don't need all that excess that find2perl throws in. Your
    whole sub body can be replaced with:

    print "$File::Find::name\n" if int(-M) < 1;

    >
    > My not-working File::Find::Rule version:
    >
    > use File::Find::Rule;
    >
    > my $rootdir = 'D:/MYDOCU~1/schema_validate';
    >
    > my @files = File::Find::Rule->file()
    > ->name( '*.pl' )
    > ->mtime ("-1")
    > ->in($rootdir);
    > foreach my $file (@files) {
    > print "$file\n";
    > }
    >
    > I've actually tried a variety of things for the mtime() method
    > but either get nothing or I get everything. It's not clear to
    > me how to apply mtime() here.


    Looking at
    http://search.cpan.org/~rclamp/File-Find-Rule-0.28/lib/File/Find/Rule.pm#Matching_Rules,


    it says to see C<stat> in perlfunc. Looking at that documentation, we
    have:
    9 mtime last modify time in seconds since the epoch

    I would say you're getting confused between the return value of -M and
    the mtime return value of stat().

    it looks to me like the proper argument would be:
    ->mtime('> ' . (time() - 24*60*60))

    That is, all files whose last modified times are greater than the
    current time minus one day (give or take for DST).

    Paul Lalli
    Paul Lalli, Jan 24, 2006
    #2
    1. Advertising

  3. Arvin Portlock

    Dr.Ruud Guest

    Arvin Portlock schreef:

    > my @files = File::Find::Rule->file()
    > ->name( '*.pl' )
    > ->mtime ("-1")
    > ->in($rootdir);


    http://www.perladvent.org/2002/11th/
    does it like this:

    my $last_week = time()-7*24*60*60;
    my @files = File::Find::Rule->file
    ->name('*.mp3')
    ->size('>=200K')
    ->mtime("<$last_week")
    ->in('/home/mark/mp3');

    but from `perldoc -f -M` I guess that should be ->mtime('>7').

    I would expect '<1' to mean '<24h', but maybe the unit is exclusively
    "seconds since epoch", like with stat.

    See also File::Finder::Steps.

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Jan 24, 2006
    #3
  4. Arvin Portlock

    J. Gleixner Guest

    Arvin Portlock wrote:

    > use File::Find::Rule;
    >
    > my $rootdir = 'D:/MYDOCU~1/schema_validate';
    >
    > my @files = File::Find::Rule->file()
    > ->name( '*.pl' )
    > ->mtime ("-1")
    > ->in($rootdir);
    > foreach my $file (@files) {
    > print "$file\n";
    > }
    >
    > I've actually tried a variety of things for the mtime() method
    > but either get nothing or I get everything. It's not clear to
    > me how to apply mtime() here.


    The value for mtime is the time the file was modified, in seconds. So
    figure out the current number of seconds, minus 1 day, of seconds.

    my $today = time();
    my $days_ago = $today - 86400; #seconds in a day

    my @files = File::Find::Rule->file()
    ->name( '*.pl' )
    ->mtime (">$days_ago")
    ->in($rootdir);


    The documentation could probably add a few more examples.
    J. Gleixner, Jan 24, 2006
    #4
  5. Arvin Portlock

    Paul Lalli Guest

    Dr.Ruud wrote:
    > Arvin Portlock schreef:
    >
    > > my @files = File::Find::Rule->file()
    > > ->name( '*.pl' )
    > > ->mtime ("-1")
    > > ->in($rootdir);

    >
    > http://www.perladvent.org/2002/11th/
    > does it like this:
    >
    > my $last_week = time()-7*24*60*60;
    > my @files = File::Find::Rule->file
    > ->name('*.mp3')
    > ->size('>=200K')
    > ->mtime("<$last_week")
    > ->in('/home/mark/mp3');
    >
    > but from `perldoc -f -M` I guess that should be ->mtime('>7').


    You, like the OP, are confusing -M with stat(). The functions are
    intimitely related (in so far that -M actually calls stat()) but their
    return values are not the same.

    -M returns the number of days since the file was last modified.
    stat()'s mtime parameter is the number of seconds since the epoch that
    the file was last modified.

    Paul Lalli
    Paul Lalli, Jan 24, 2006
    #5
  6. Paul Lalli wrote:

    > Arvin Portlock wrote:
    >
    > >I'm trying to use File::Find::Rule to get files modified in
    > >the last 24 hours.


    > fwiw, you don't need all that excess that find2perl throws in. Your
    > whole sub body can be replaced with:
    >
    > print "$File::Find::name\n" if int(-M) < 1;


    That's nice. My biggest argument with File::Find is that
    it's hard to encapsulate it within a larger program. I
    see a couple of different ways to do it but they're both
    ugly and not very perl-ish.

    > >my @files = File::Find::Rule->file()
    > > ->name( '*.pl' )
    > > ->mtime ("-1")
    > > ->in($rootdir);


    > it looks to me like the proper argument would be:
    > ->mtime('> ' . (time() - 24*60*60))


    And that did the trick, Thank you. Believe it or not I
    tried something almost identical to that. I think I
    didn't have the > in there though. Probably I would have
    stumbled on it sooner or later.

    Thanks Everybody!
    Arvin Portlock, Jan 24, 2006
    #6
  7. >>>>> "Arvin" == Arvin Portlock <> writes:


    Arvin> my @files = File::Find::Rule->file()
    Arvin> -> name( '*.pl' )
    Arvin> -> mtime ("-1")
    Arvin> -> in($rootdir);
    Arvin> foreach my $file (@files) {
    Arvin> print "$file\n";
    Arvin> }

    In File::Finder, that'd be:

    my @files = File::Finder
    ->name('*.pl')
    ->mtime('-1')
    ->in($rootdir);

    File::Finder uses find(1) primitives, which I find easier to understand
    than File::Find::Rule's mix of find(1) and ad-hoc constructs.

    --
    Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
    <> <URL:http://www.stonehenge.com/merlyn/>
    Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
    See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
    Randal L. Schwartz, Jan 24, 2006
    #7
  8. Arvin Portlock

    Dr.Ruud Guest

    Paul Lalli schreef:
    > Dr.Ruud wrote:
    >> Arvin Portlock schreef:
    >>
    >>> my @files = File::Find::Rule->file()
    >>> ->name( '*.pl' )
    >>> ->mtime ("-1")
    >>> ->in($rootdir);

    >>
    >> http://www.perladvent.org/2002/11th/
    >> does it like this:
    >>
    >> my $last_week = time()-7*24*60*60;
    >> my @files = File::Find::Rule->file
    >> ->name('*.mp3')
    >> ->size('>=200K')
    >> ->mtime("<$last_week")
    >> ->in('/home/mark/mp3');
    >>
    >> but from `perldoc -f -M` I guess that should be ->mtime('>7').

    >
    > You, like the OP, are confusing -M with stat().


    Well, I was leaving it to the OP to find out which formats are allowed,
    qr{[+-><]?\d+} days or qr{\d+} epoch-seconds or even both and more. That
    information is quite hard to find, and obscured by examples everywhere
    that freely use all kinds of formats with mtime.
    The documentation of File::Find::Rule limits it to epoch seconds and
    Number::Compare semantics. It has ->modified for -M, and ->mtime for
    stat[9].


    > The functions are
    > intimitely related (in so far that -M actually calls stat()) but their
    > return values are not the same.
    >
    > -M returns the number of days since the file was last modified.
    > stat()'s mtime parameter is the number of seconds since the epoch that
    > the file was last modified.


    Yes, that was not the problem, but nowhere (that I could find) was made
    clear whether File:Find's mtime is in (relative) days, or in epoch
    seconds, or that even other formats like '2005-12-25' are OK too.


    From the documentation of 'nephew' File::Finder::Steps:

    my $big_or_old = File::Finder
    ->type('f')
    ->left
    ->size("+100")->or->mtime("+90")
    ->right;
    find($big_or_old->ls, "/tmp");

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Jan 24, 2006
    #8
  9. Arvin Portlock wrote:

    > I'm trying to use File::Find::Rule to get files modified in
    > the last 24 hours.


    > My not-working File::Find::Rule version:
    >
    > use File::Find::Rule;
    >
    > my $rootdir = 'D:/MYDOCU~1/schema_validate';
    >
    > my @files = File::Find::Rule->file()
    > ->name( '*.pl' )
    > ->mtime ("-1")
    > ->in($rootdir);
    > foreach my $file (@files) {
    > print "$file\n";
    > }


    This thread has become very interesting for me. Thanks for
    all the input. One interesting thing that was causing me
    problems and contributed to my overall confusion vis-à-vis
    mtime () was that my program wouldn't work if I included
    the program's directory in the search path. Something odd
    happens when the program attempts to retrieve itself in
    the list of files. No error message, I would simply get no
    results. I didn't notice this problem until a few minutes
    ago, so was trying a wide variety of crazy things to get
    it to work. A few evals done early might have revealed
    the problem.

    Might be a Windows-specific problem.
    Arvin Portlock, Jan 24, 2006
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rahmi Acar
    Replies:
    0
    Views:
    559
    Rahmi Acar
    Jul 17, 2003
  2. Thomas W
    Replies:
    2
    Views:
    599
    Fredrik Lundh
    Mar 16, 2005
  3. Replies:
    0
    Views:
    1,356
  4. AShopper.net
    Replies:
    0
    Views:
    323
    AShopper.net
    Nov 26, 2007
  5. rutherf
    Replies:
    2
    Views:
    424
    rutherf
    Oct 28, 2006
Loading...

Share This Page