http://qs321.pair.com?node_id=1032273


in reply to Perl ranges

foreach (@array_of_filenames) { my $mtime = (stat($_))[9]; # Get mtime for file my $month = (localtime($mtime))[4] +1; # Get month for file my $day = (localtime($mtime))[3]; # Get day of month for file my $thismtime = (stat())[9]; # Get mtime for today my $thismonth = (localtime())[4] +1; # Get this month if ($month == $thismonth and $day >= 21) { print "Filename: $_\n"; + } }

Anne

Replies are listed 'Best First'.
Re^2: Perl ranges
by runrig (Abbot) on May 06, 2013 at 20:24 UTC
    stat does not stat files over FTP. You can use the Net::FTP mdtm method to get the files mtime (supposed to be UTC which may not match the date/time you see in a dir listing).

      Good catch, runrig. I only tested my code snippet locally and it didn't occur to me that I was using localtime() locally, even though the file stat info would be from another host. I'm too used to relying on my ssh configs and the command line to do things like that:

        $ ssh somedomain.com somecommand

      Running stat on the remote host would give me the remote localtime. But that's not what the OP is doing.

      Thanks

      Anne

Re^2: Perl ranges
by merlin's apprentice (Novice) on May 06, 2013 at 13:34 UTC

    Hi Anne, I'd really like for this to only get me those files that have an 'mtime' of between 2013-03-20 and 2013-04-21. How do I get this to do that? PS: I'm very new to perl and taking 'baby' steps at it which is why I'd like your help with this :)

      New to programming in general I take it?

      Often the thing to do is ask yourself "how do you do it manually?", and then have the computer do it the same way. There are usually tricks, standard algorithms and modules to do it, but at the core of it all is figuring out what steps need to be followed to accomplish a goal.

      How do you compare two dates manually? Myself, I do:

      1. Look at the year first. Is it bigger, smaller or the same? If it is smaller or bigger, then you're done. Otherwise, go to step 2
      2. Look at the month next. Is it bigger, smaller or the same?
      3. Still the same? Check the day next.
      4. Still the same? Then the dates are the same.

      A convenient operator for this sort of sequence in general is <=> it returns -1, 0 or +1 depending on whether the left side is smaller,equal, or bigger than the right side. Combine that with or, which will return the left side if it is true, otherwise return the right side. (Standard boolean logic: false or true => true, false or false => false, true or anything => true)

      my $result = $startRange eq 'any' or $year <=> $startRangeYear  or $month <=> $startRangeMonth  or $day <=> $startRangeDay;

      Dates in particular have a nice property that lets you compare them even easier. Write the date as a number with zero padding: 20130506 and compare it to some other date given the same treatment: 20121225. Now it is trivial to see if one date is less than, equal or greater than another. my $ymd = sprintf('%04d%02d%02d', $year, $month, $day);

      Welcome to perl!

      Stick with it. It is useful for so many things and there is help to be had in many places.

      I've provided you with some code for tutorial purposes but I'd recommend going with Mikes because it is more elegant and versatile.

      The script below works on files in the current directory containing the perl script.

      For information on $|, visit Suffering from Buffering. It basically makes sure your output comes out as expected.

      For more information on perl, such as the localtime() and stat(), functions, checkout perl.org and your local ActiveState documentation and, of course, Google is your friend.

      use strict; use warnings; $|=1; # Buffering my @filenames; opendir DIR, "." or die "Failed while trying to open current directory +\nPerl says: \n$!"; @filenames = readdir DIR; # Get list of files in current directory shift @filenames; shift @filenames; # remove . and .. foreach (@filenames) { my $mtime = (stat($_))[9]; # Get mtime for file my $year = (localtime($mtime))[5] + 1900; # Get year for file my $month = (localtime($mtime))[4] +1; # Get month for file my $day = (localtime($mtime))[3]; # Get day of month for file if ($month >= 03 and $year == "2013") { if ($month == 03 and $day >=20) { print "Filename: $_\n"; } if ($month == 04 and $day <=21) { print "Filename: $_\n"; } } }

      The code to drop in your script might be: (Warning: Not tested)

      my @filenames = parse_dir($ls); foreach (@filenames) { my $mtime = (stat($_))[9]; # Get mtime for file my $year = (localtime($mtime))[5] + 1900; # Get year for file my $month = (localtime($mtime))[4] +1; # Get month for file my $day = (localtime($mtime))[3]; # Get day of month for file if ($month >= 03 and $year == "2013") { if ($month == 03 and $day >=20) { print "Filename: $_\n"; } if ($month == 04 and $day <=21) { print "Filename: $_\n"; } } }

      Anne

        It failed after I updated the system...

        I haven't the faintest clue what modules to download and make it work again

        what modules do you think are missing?

        here are those listed by

         instmodsh -l

        CPAN CPANPLUS Expect File::Listing HTTP::Date Module::Load::Conditional Net::SSLeay Object::Accessor Params::Check Perl Sub::Uplevel Test::Exception