#!/bin/bash set -e function _help() { echo ' Usage: file-age {file} [units] Checks file modification date, and the current time. Prints the age of the file in [units]. [units] is one of S, M, H, d, w, m, y, full, human seconds is the default. All values floored. month = 30 days year = 365 days full = YY-MM-DD hh:mm:ss human = 3 months 2 days ' exit } for (( i=1; i<=$#; i++ )) do [[ "${!i}" = "-h" ]] && _help done function _human { file_date=( $( date -r "$STATFILE" +"%Y %m %d %H %M %S" ) ) current_date=( $( date +"%Y %m %d %H %M %S" ) ) local values=() for (( i=0; $i<${#file_date[@]}; i++ )); do values+=( $(( ${current_date[$i]#0} - ${file_date[$i]#0})) ) done if [[ ${values[5]} -lt 0 ]]; then values[5]=$(( 60 + ${values[5]} )); values[4]=$(( ${values[4]} -1 )) fi if [[ ${values[4]} -lt 0 ]]; then values[4]=$(( 60 + ${values[4]} )); values[3]=$(( ${values[3]} -1 )) fi if [[ ${values[3]} -lt 0 ]]; then values[3]=$(( 24 + ${values[3]} )); values[2]=$(( ${values[2]} -1 )) fi if [[ ${values[2]} -lt 0 ]]; then case ${file_date[1]#0} in 1|3|5|7|8|10|12) mlen=31;; 2) mlen=28;; *) mlen=30;; esac values[2]=$(( $mlen + ${values[2]} )); values[1]=$(( ${values[1]} -1 )) fi if [[ ${values[1]} -lt 0 ]]; then values[1]=$(( 12 + ${values[1]} )); values[0]=$(( ${values[0]} -1 )) fi if [[ "$1" = "full" ]]; then printf '%02d-%02d-%02d %02d:%02d:%02d\n' ${values[@]} return fi local units=( yr mo day hr min sec ) if [[ "${file_date[@]}" = "${current_date[@]}" ]]; then printf " 0 sec\n"; return fi for (( i=0; $i<${#values[@]}; i++ )); do if [[ ${values[$i]} -gt 0 ]]; then j=$(( i + 1 )) printf "%2s %-3s" ${values[$i]} ${units[$i]} if [[ $j -lt ${#values[@]} ]]; then printf " %2s %-3s" ${values[$j]} ${units[$j]} break fi fi done printf "\n" } STATFILE="$1" [[ -z "$STATFILE" ]] && _help test -e "$STATFILE" || { echo File "$STATFILE" does not exist >&2; exit 1; } UNITS=${2:-S} case $OSTYPE in darwin*) created=$( stat -f %c -t %s "$STATFILE" ) ;; *) created=$( stat -c %Y "$STATFILE" ) ;; esac now=$( date +%s ) age=$(( $now - $created )) case $UNITS in S) echo $age ;; M) echo $(( $age / 60 )) ;; H) echo $(( $age / 3600 )) ;; d) echo $(( $age / 86400 )) ;; w) echo $(( $age / 604800 )) ;; m) echo $(( $age / 2592000 )) ;; y) echo $(( $age / 31536000 )) ;; full) _human full;; human) _human;; *) echo Unit $UNITS not recognized. _help ;; esac