Last active
September 7, 2022 01:39
-
-
Save Rio6/1c4ae5237451b13bc2be7fa1da1229ce to your computer and use it in GitHub Desktop.
Prune list of backup files to be daily, weekly, monthly, and yearly depending on the backup age.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# usage: prune-backup [-f] files... | |
# By default the script prints files to be deleted. Use -f to actually delete. | |
# Assuming the file names have format of %Y-%m-%dT* | |
# exit on failure, disable glob | |
set -ef | |
filter_date() { | |
format="$1" | |
match="$2" | |
op="${3:--eq}" | |
while read file; do | |
date="${file##*/}" | |
date="${date%T*}" | |
if [ $(date -d "$date" "+$format") "$op" "$match" ]; then | |
echo "$file" | |
fi | |
done | |
} | |
if [ "$1" = "-f" ]; then | |
dry= | |
else | |
dry=1 | |
fi | |
files="$(printf '%s\n' "$@")" | |
today=$(date -d $(date +%F) +%s) | |
last_week="$(expr "$today" - 604800)" | |
last_month="$(expr "$today" - 2592000)" # assume 30 day month | |
last_year="$(expr "$today" - 31536000)" # assume 365 day year | |
# finding files to prune by printing the ones to keep on top of file list then | |
# filter out the duplicates. The filters here are in parallel, in theory | |
# there's a probability of lines interrupting each other when the line length | |
# exceeds stdout buffer, but in practice file name sizes are restricted to be | |
# much smaller than stdout buffer size so it should be fine. | |
prune=$( ( | |
echo "$files" | filter_date %s "$last_week" -ge; # in the past week | |
echo "$files" | filter_date %s "$last_month" -ge | filter_date %w 1 -eq; # in the pat month and every monday | |
echo "$files" | filter_date %s "$last_year" -ge | filter_date %d 1 -eq; # in the pat montyear and first of every month | |
echo "$files" | filter_date %j 1 -eq; # first of every year | |
echo "$files" | |
) | sort | uniq -u) | |
IFS=' | |
' | |
if [ "$dry" ]; then | |
printf '%s\n' $prune | |
else | |
rm -fv $prune | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment