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

Hi , I have few log files created with date as part of the name of the file abcd1.20110429-2345 abcd2.20110502-2345 abcd3.20110505-2345 abcd3.20110509-2345 I need to extract the date out of file names(20110429) and then for all files with date less than a week then i need to parse them and extract some info out it I am not able to extract date and then subtract from the sytem/todays date to find a weeks difference I am thinking of doing a reverse sort on the dates after i extract them Can any one please help me on this ? Many thanks, Zac

Replies are listed 'Best First'.
Re: date as part of filename
by roboticus (Chancellor) on May 12, 2011 at 22:27 UTC

    zac_carl:

    Extracting the date from the filename should be simple enough, something like this ought to do it:

    my $fname = 'abcd1.20110429-2345'; my $date = 'NOT FOUND'; if ($fname =~ /(20\d{6})-\d{4}/) { $date = $1; } print $date,"\n";

    For comparing date ranges, I'd suggest hitting up CPAN for some modules like DateTime.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      Thanks roboticus .. I dont have any modules CPAN MODULES install for the date though. I would have multiple files like this and want to reverse sort them according to the extracted date and from subtract them to identify <=7 date files and process them
        Time::Piece is a core module, and should be able to parse (strptime), format (strftime), and subtract days from an arbitrary date.

        zac_carl:

        While I would suggest using some CPAN goodness, if you're set against it, then you ought to read perldoc perlfunc and review interesting functions like localtime to see how you might accomplish the job.

        ...roboticus

        When your only tool is a hammer perl, all problems look like your thumb reimplementing CPAN (poorly).

Re: date as part of filename
by wind (Priest) on May 12, 2011 at 22:51 UTC

    Since your dates are already in a format that is easily sorted, just use a simple '>' comparison to the one week ago date value.

    use DateTime; use strict; use warnings; my $oneweekago = DateTime->now()->subtract(days => 7)->strftime("%Y%m% +d"); while (<DATA>) { print if /(\d{8})/ && $1 > $oneweekago; } =prints abcd3.20110509-2345 =cut __DATA__ abcd1.20110429-2345 abcd2.20110502-2345 abcd3.20110505-2345 abcd3.20110509-2345

    Update: Changed implementation from POSIX to DateTime per ikegami

      I can't find anything that says the time components can be negative. Any idea what POSIX (the spec, not the module) says?

        Good Question, it's an undocumented feature that I've simply observed others using from time to time.

        However, testing it shows that it works across month boundaries, but fails on year boundaries

        use POSIX qw(strftime); use strict; use warnings; my @date = localtime; while (<DATA>) { my ($year, $mon, $day, $expected) = split; @date[3,4,5] = ($day, $mon, $year); my $fmt = strftime "%Y%m%d", @date; print "$fmt <=> $expected " . ($fmt eq $expected ? 'matched' : 'fa +iled') . "\n"; } =prints 20110501 <=> 20110501 matched 20110430 <=> 20110430 matched 20110429 <=> 20110429 matched 20110102 <=> 20110102 matched 20110101 <=> 20110101 matched 20110512 <=> 20101231 failed 20110512 <=> 20101230 failed =cut __DATA__ 111 4 1 20110501 111 4 0 20110430 111 4 -1 20110429 111 0 2 20110102 111 0 1 20110101 111 0 0 20101231 111 0 -1 20101230

        Truth is, using DateTime is cleaner anyway, so will update my script.