How do I check whether my file was modified in a certain month or date range?

Doing date-related math in Bash is hard because Bash has no builtins in place for doing math with dates or getting metadata such as modification time from files.

There is the stat(1) but it is highly unportable; even across different GNU operating systems. While most machines have a stat, they all take different arguments and syntax. So, if the script must be portable, you should not rely on stat(1). There is an example loadable builtin called finfo that can retrieve file metadata, but it's not available by default either.

What we do have are test (or [[) which can check whether a file was modified before or after another file (using -nt or -ot) and touch which can create files with a specified modification time. Combining these, we can do quite a bit.

For example, a function to test whether a file was modified in a certain date range:

inTime() {
    set -- "$1" "$2" "${3:-1}" "${4:-1}" "$5" "$6" # Default month & day to 1.
    local file=$1 ftmp="${TMPDIR:-/tmp}/.f.$$" ttmp="${TMPDIR:-/tmp}/.t.$$"
    local fyear=${2%-*} fmonth=${3%-*} fday=${4%-*} fhour=${5%-*} fminute=${6%-*}
    local tyear=${2#*-} tmonth=${3#*-} tday=${4#*-} thour=${5#*-} tminute=${6#*-}

    touch -t "$(printf '%02d%02d%02d%02d%02d' "$fyear" "$fmonth" "$fday" "$fhour" "$fminute")" "$ftmp"
    touch -t "$(printf '%02d%02d%02d%02d%02d' "$tyear" "$tmonth" "$tday" "$thour" "$tminute")" "$ttmp"

    (trap 'rm "$ftmp" "$ttmp"' RETURN; [[ $file -nt $ftmp && $file -ot $ttmp ]])
}

Using this function, we can check whether a file was modified in a certain date range. The function takes several arguments: A filename, a year-range, a month-range, a day-range, an hour-range, and a minute-range. Any range may also be a single number in which case the beginning and end of the range will be the same. If any range is unspecified or omitted, it defaults to 0 (or 1 in the case of month/day).

Here's a usage example:

    $ touch -t 198404041300 file
    $ inTime file 1984 04-05 && echo "file was last modified in April of 1984"
    file was last modified in April of 1984
    $ inTime file 2010 01-02 || echo "file was not last modified in January 2010"
    file was not last modified in Januari 2010
    $ inTime file 1945-2010 && echo "file was last modified after The War"
    file was last modified after The War


CategoryShell

BashFAQ/103 (last edited 2015-09-28 19:14:05 by GreyCat)