Skip to content

Instantly share code, notes, and snippets.

@rhietala
Last active January 29, 2019 11:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rhietala/00a76ee7fa1d5b56978b945ba0fff8be to your computer and use it in GitHub Desktop.
Save rhietala/00a76ee7fa1d5b56978b945ba0fff8be to your computer and use it in GitHub Desktop.
#!/bin/bash
# Old files removal tool
#
# This script can be used to remove old files (e.g. daily backups)
# so that some are kept.
#
# Files are kept if they are:
# - Less than 30 days old
# - Less than a year old and created on monday
# - Created on 1st of any month
#
# Only files in given path and its subdirectories that end with .gz are
# included.
#
# Empty directories under given path will be also removed after files
# are checked.
#
#
# Dry run usage (doesn't remove any files, just prints statistics):
# ./remove-files.sh <path>
#
# Real usage (removes files):
# ./remove-files.sh <path> --remove
#
# Required commands (must be in path):
# date, stat, rm, bc, find
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
set -e # exit if any command fails
FILES_PATH=$1
REMOVE=$2
if [ -z "$FILES_PATH" ]; then
echo "Usage: ./remove-old-backups.sh <backup path> [--remove]"
exit 1
fi
if [ "$REMOVE" == "--remove" ]; then
echo "Starting to remove old backups from $FILES_PATH"
else
echo "Starting to remove old backups from $FILES_PATH DRY RUN (doesn't actually remove anything)"
fi
scanned=0
kept=0
removed=0
CURRENT_TIMESTAMP=`date +%s`
TIMESTAMP_MONTH_AGO=`echo "$CURRENT_TIMESTAMP - (30 * 24 * 60 * 60)" | bc`
TIMESTAMP_YEAR_AGO=`echo "$CURRENT_TIMESTAMP - (12 * 30 * 24 * 60 * 60)" | bc`
# loop through all files and directories in this path, and
# subdirectories
for f in $FILES_PATH/* $FILES_PATH/**/* ; do
# skip unless $f is a file
if [ ! -f $f ] ; then
continue
fi
# skip unless $f ends with .gz
EXT="${f##*.}"
if [ $EXT != "gz" ] ; then
continue
fi
scanned=$((scanned+1))
MODIFIED_TIMESTAMP=`stat -c %Y $f`
MODIFIED_WEEKDAY=`date -d @$MODIFIED_TIMESTAMP +%u` # 1 is monday
MODIFIED_DAYNUM=`date -d @$MODIFIED_TIMESTAMP +%d` # 01 is first of month
# keep files that
# - last modification is on monday and under a year ago
# - last modification is on first of month
# - last modification is under 30 days ago
if [[ ( $MODIFIED_WEEKDAY == "1" && \
$MODIFIED_TIMESTAMP -ge $TIMESTAMP_YEAR_AGO ) || \
$MODIFIED_DAYNUM == "01" || \
$MODIFIED_TIMESTAMP -ge $TIMESTAMP_MONTH_AGO \
]] ; then
kept=$((kept+1))
else
if [ "$REMOVE" == "--remove" ]; then
rm $f
fi
removed=$((removed+1))
fi
done;
if [ "$REMOVE" == "--remove" ]; then
find $FILES_PATH -type d -empty -delete
echo "Finished cleaning backups from $FILES_PATH: scanned: $scanned, kept: $kept, removed: $removed"
else
echo "Finished cleaning backups from $FILES_PATH: scanned: $scanned, kept: $kept, removed: $removed DRY RUN (nothing removed)"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment