5

I want to find files older than N days from a given timestamp in format YYYYMMDDHH

I can find file older than 2 days with the below command, but this finds files with present time:

find /path/to/dir -mtime -2 -type f -ls

Lets say I give the input timestamp=2011093009 I want to find files older than 2 days from 2011093009.

Been doing my research, but can't seem to figure it out.

Wouter J
  • 41,455
  • 15
  • 107
  • 112
esausilva
  • 1,964
  • 4
  • 26
  • 54
  • recursively? current directory? – ormaaj Jun 28 '12 at 16:08
  • yes, recursively..all files under `/path/to/dir ` – esausilva Jun 28 '12 at 20:49
  • Should the command to find older than 2 days be `find /path/to/dir -mtime +2 -type f -ls`? I tried this and on my system (xubuntu, bash) the `-2` option to `-mtime` would find files newer than 2 days. – jhonkola Feb 13 '13 at 11:05
  • I dislike -mtime because I feel it's too "relative". For a more "absolute" solution, try "touch -t" to create files with the relevant timestamps, and then find's "-newer" and "!" operators. –  Jan 15 '15 at 13:23

3 Answers3

0

put one of the answers from here and using $() as suggested here

(updated as per comment by sputnick)

date=2011060109; find /home/kenjal/ -mtime $(( $(date +%Y%m%d%H) - $(date -d $date +%Y%m%d%H) ))
Community
  • 1
  • 1
Kinjal Dixit
  • 7,777
  • 2
  • 59
  • 68
  • 2
    `expr` is the old fashion ;) `date=2011060109; find /home/kenjal/ -mtime $(( $(date +%Y%m%d%H) - $(date -d $date +%Y%m%d%H) ))` – Gilles Quénot Jun 28 '12 at 15:50
  • This requires GNU date of course (the -d option is not portable). Also, I don't think this anwsers the original question; he wants files OLDER than N days from some date. Not sure how to do this myself... – BellevueBob Jun 28 '12 at 16:30
  • Bob Duell: You a correct, I want files OLDER than N days from some date. And yes, I do not have GNU date, so `-d` option does not work for me – esausilva Jun 28 '12 at 20:46
  • kinjal: Thanks for your answer, the link you provided guided me to get the correct answer, took me some time, but finally got it :). I'll post it in a bit... – esausilva Jun 28 '12 at 20:47
0

Basically this is accomplished by finding files in a range of dates...

I used perl to calculate the days from today to the given timestamp since GNU date is not available in my system, so -d is not an option. Code Below accepts date in format YYYYDDMM. See below:

#!/usr/bin/perl 
use Time::Local;

my($day, $month, $year) = (localtime)[3,4,5];
$month = sprintf '%02d', $month+1;
$day   = sprintf '%02d', $day;
my($currentYear, $currentDM) = ($year+1900, "$day$month");
my $todaysDate = "$currentYear$currentDM";
#print $todaysDate;

sub to_epoch {
    my ($t) = @_;  
    my ($y, $d, $m) = ($t =~ /(\d{4})(\d{2})(\d{2})/); 
    return timelocal(0, 0, 0, $d+0, $m-1, $y-1900);
}
sub diff_days {
    my ($t1, $t2) = @_;  
    return (abs(to_epoch($t2) - to_epoch($t1))) / 86400; 
}
print diff_days($todaysDate, $ARGV[0]);

**Note: I'm no expert in Perl and this is the very first piece of code I modify/write. Having said that, I'm sure there are better ways to accomplish the above in Perl

Then the below korn script to perform what I needed.

#!/bin/ksh
daysFromToday=$(dateCalc.pl 20110111)
let daysOld=$daysFromToday+31
echo $daysFromToday "\t" $daysOld

find /path/to/dir/ -mtime +$daysFromToday -mtime -$daysOld -type f -ls

I'm finding all files older than +$daysFromToday, then narrowing the search to days newer than -$daysOld

esausilva
  • 1,964
  • 4
  • 26
  • 54
0
#!/usr/bin/env bash

# getFiles arrayName olderDate newerDate [ pathName ]
getFiles() {
    local i
    while IFS= read -rd '' "$1"'[(_=$(read -rd "" x; echo "${x:-0}")) < $2 && _ > $3 ? ++i : 0]'; do 
        :
    done < <(find "${4:-.}" -type f -printf '%p\0%Ts\0')
}

# main date1 date2 [ pathName ]
main() {
    local -a dates files
    local x
    for x in "${@:1:2}"; do
        dates+=( "$(date -d "$x" +%s)" ) || return 1
    done

    _=$dates let 'dates[1] > dates && (dates=dates[1], dates[1]=_)'
    getFiles files "${dates[@]}" "$3"
    declare -p files
}

main "$@"

# vim: set fenc=utf-8 ff=unix ts=4 sts=4 sw=4 ft=sh nowrap et:

This Bash script takes two dates and a pathname for find. getFiles takes an array name and the files with mtimes between the two dates are assigned to that array. This example script simply prints the array.

Requires a recent Bash, and GNU date. If it really has to be "N days", or you don't have GNU date, then there is no possible solution. You'll need to use a different language. No shell can do that using standard utilities.

Technically, you can calculate an offset in days using printf '%(%s)T' ... and some arithmetic, but there is no possible way to get the base date from a timestamp without GNU date, so I'm afraid you're out of luck.

Edit

I see this question has a ksh tag, in which case I lied, apparently ksh93's printf accepts a GNU date -d like string. I have no idea whether it's portable, and of course requires a system with ksh93 installed. You could do it in that case with some modification to the above script.

ormaaj
  • 6,201
  • 29
  • 34
  • thank you for your response...unfortunately, my system does not have GNU date, so `-d` is not an option...but, with a little more research, I have figured out an answer to my question. you can take a look at my accepted answer – esausilva Jul 03 '12 at 02:11
  • Yeah that's ok, I noticed in your other comments just as I finished with this. I hope someone finds it useful anyway. – ormaaj Jul 03 '12 at 02:37