file-watch-do - Watch a file or directory and each time it or a member is modified run a command

#!/usr/bin/env bash
help_text="
NAME
    file-watch-do - Watch a file (or directory) and each time it is modified run a command.

USAGE
    file-watch-do [options] <file name> <command> [<command parameters>]

OPTIONS

    -f|--frequency <seconds>
        Set the frequency of checks in seconds. Default is 1 second.

DESCRIPTION
    Watch a file (or directory) and each time the file or a file within the directory is 
    modified run a command.

AUTHOR
    mjnurse.github.io - 2019
"
help_line="Watch a file or directory and each time it or a member is modified run a command"
web_desc_line="Watch a file or directory and each time it or a member is modified run a command"
pack_member="default"

name=${0/\.\/}
try="Try '$name -h' for more information"

# Get usage from help_text.
usage=${help_text##*USAGE}
usage=${usage%%OPTIONS*}
usage=${usage%%PARAMETERS*}
usage=${usage%%DESCRIPTION*}
usage=${usage//[$'\n\r']}
usage=${usage##*   }
usage="Usage: ${usage}"

if [[ "$1" == "-f" || "$1" == "--frequency" ]]; then
    shift
    SLEEP_TIME=$1
    shift
else
    SLEEP_TIME=1
fi

FD="f"  # File or directory flag

function get_date {
    if [[ "$FD" == "f" ]]; then
        date -r "$1"
    else
        st=$(date +"%H%M%S%N")
        find "$1" -type f -printf '%T@ %p\n' | sort -n | tail -1
        ed=$(date +"%H%M%S%N")
        if [[ $((ed - st)) -gt 500000000 ]]; then
            echo "Warning: Scanning directory '$1' is taking > 0.5s"
        fi
    fi
}

case "$1" in
    --help|-h|\?)
        echo "$help_text"
        exit
        ;;
esac

if [[ "$2" == "" ]]; then
    echo "$usage"
    echo "$try"
    exit
fi

file_name=$1
if [[ -f "$file_name" ]]; then
    echo "Watching file: $file_name"
    FD="f"
elif [[ -d "$file_name" ]]; then
    echo "Watching directory: $file_name"
    FD="d"
else
    echo "Error: File or directory '$file_name' not found"
    exit 1
fi

shift

prev_file_date=$(get_date "$file_name")
file_date=$prev_file_date
while [ 1 ]; do
    while [[ "$file_date" == "$prev_file_date" ]]; do
        sleep $SLEEP_TIME
        file_date=$(get_date "$file_name")
    done
    prev_file_date=$file_date
    echo
    echo "------------------------------------------------------------"
    echo $prev_file_date -  Run: "$*"
    echo "------------------------------------------------------------"
    $*
    echo "------------------------------------------------------------"
    echo "Run Complete"
    echo "------------------------------------------------------------"
    echo
done