How to keep: daily backups for a week, weekly for a month, monthly for a year, and yearly after that
Solution 1:
You are seriously over-engineering this. Badly.
Here's some pseudocode:
- Every day:
- make a backup, put into
daily
directory - remove everything but the last 7
daily
backups
- make a backup, put into
- Every week:
- make a backup, put into
weekly
directory - remove everything but the last 5
weekly
backups
- make a backup, put into
- Every month:
- make a backup, put into
monthly
directory - remove everything but the last 12
monthly
backups
- make a backup, put into
- Every year:
- make a backup, put into
yearly
directory
- make a backup, put into
The amount of logic you have to implement is about the same, eh? KISS.
This looks easier:
s3cmd ls s3://backup-bucket/daily/ | \
awk '$1 < "'$(date +%F -d '1 week ago')'" {print $4;}' | \
xargs --no-run-if-empty s3cmd del
Or, by file count instead of age:
s3cmd ls s3://backup-bucket/daily/ | \
awk '$1 != "DIR"' | \
sort -r | \
awk 'NR > 7 {print $4;}' | \
xargs --no-run-if-empty s3cmd del
Solution 2:
If you just want to keep, for example, 8 daily backups and 5 weekly (every sunday) backups, it works like this:
for i in {0..7}; do ((keep[$(date +%Y%m%d -d "-$i day")]++)); done
for i in {0..4}; do ((keep[$(date +%Y%m%d -d "sunday-$((i+1)) week")]++)); done
echo ${!keep[@]}
As of today (2014-11-10), this will output:
20141012 20141019 20141026 20141102 20141103 20141104
20141105 20141106 20141107 20141108 20141109 20141110
As an exercise left for you, you just have to delete all backup files whose names do not appear in the keep
-array.
If you want to keep 13 monthly backups (first sunday of every month) and 6 yearly backups (first sunday of every year) as well, things get a little bit more complicated:
for i in {0..7}; do ((keep[$(date +%Y%m%d -d "-$i day")]++)); done
for i in {0..4}; do ((keep[$(date +%Y%m%d -d "sunday-$((i+1)) week")]++)); done
for i in {0..12}; do
DW=$(($(date +%-W)-$(date -d $(date -d "$(date +%Y-%m-15) -$i month" +%Y-%m-01) +%-W)))
for (( AY=$(date -d "$(date +%Y-%m-15) -$i month" +%Y); AY < $(date +%Y); AY++ )); do
((DW+=$(date -d $AY-12-31 +%W)))
done
((keep[$(date +%Y%m%d -d "sunday-$DW weeks")]++))
done
for i in {0..5}; do
DW=$(date +%-W)
for (( AY=$(($(date +%Y)-i)); AY < $(date +%Y); AY++ )); do
((DW+=$(date -d $AY-12-31 +%W)))
done
((keep[$(date +%Y%m%d -d "sunday-$DW weeks")]++))
done
echo ${!keep[@]}
As of today (2014-11-10), this will output:
20090104 20100103 20110102 20120101 20130106 20131103
20131201 20140105 20140202 20140302 20140406 20140504
20140601 20140706 20140803 20140907 20141005 20141012
20141019 20141026 20141102 20141103 20141104 20141105
20141106 20141107 20141108 20141109 20141110
Same as above, just delete all backup files not found in this array.