Skip to content

Instantly share code, notes, and snippets.

@colemar
Last active November 23, 2022 21:09
Show Gist options
  • Save colemar/46c3dce627259084b1b8fde62c10a51f to your computer and use it in GitHub Desktop.
Save colemar/46c3dce627259084b1b8fde62c10a51f to your computer and use it in GitHub Desktop.
Find Files in Time Range

Find Files in Time Range

Recursively search for all files whose last modification time is in a specified range.

fftr path {time|file} range [b]

where:

  • path is where to start the search
  • time is any format understood by date -d
  • file is a reference file (now is a time, hence use ./now)
  • range in seconds; +N after time, -N before time, N centered on time
  • (optional) b means bare output

Examples

  • find files modified at most 2 day ago: fftr . now -2*24*60*60
  • find files modified at most 1 second before or after the time of myfile: fftr . myfile 2
  • find files modified at most 2 hours after the time of a file named 'now': fftr ./now +2*60*60
  • move files modified at most 7 days ago: mv $(fftr . now -7*24*60*60 b) /else/where

Screenshots

Screenshot Screenshot Screenshot

#!/usr/bin/bash
error_exit () {
echo -e "error: $1" >&2
exit 1
}
(( $# >= 3 && $# <= 4 )) || error_exit "
Find Files in Time Range:
Recursively searches for all files whose last modification time is in a specified range.
${0##*/} path {time|file} range [b]
where:
- path is where to start the search
- time is any format understood by [date -d]
- file is a reference file ('now' is a time, hence use './now')
- range in seconds; +N after time, -N before time, N centered on time
- (optional) b means bare output
Examples:
- find files modified at most 2 days ago: ${0##*/} . now -2*24*3600
- find files modified at most 1 second before or after the time of myfile: ${0##*/} . myfile 2
- find files modified at most 2 hours after the time of a file named 'now': ${0##*/} ./now +2*60*60"
for cmd in date stat find; do
command -v $cmd >/dev/null || error_exit "missing command $cmd"
done
if time=$(date -d "$2" +%s 2>/dev/null)
then
echo "given time: $(date -d @$time)" >&2
else
time=$(stat -c %Y "$2" 2>/dev/null) || error_exit "cannot interpret '$2' as time nor ref file"
echo "reference file modification time: $(date -d @$time)" >&2
fi
cd $1 || error_exit "not a path or not accessible: $1"
typeset -i dev=$3
(( dev == 0 )) && error_exit "invalid range: $3"
case "$3" in
+*) lot=$time; hit=$((lot+dev)) ;;
-*) hit=$time; lot=$((hit+dev)) ;;
*) lot=$((time-dev/2)); hit=$((lot+dev)) ;;
esac
[[ "$4" > '' ]] || opt=-ls
echo -e "time range: $(date -d @$lot) ... $(date -d @$hit)\n" >&2
find . -type f -newermt @$lot -not -newermt @$hit $opt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment