diff options
| author | David Vazgenovich Shakaryan <dvshakaryan@gmail.com> | 2023-03-23 18:53:52 -0700 | 
|---|---|---|
| committer | David Vazgenovich Shakaryan <dvshakaryan@gmail.com> | 2023-03-23 18:53:52 -0700 | 
| commit | 1cf9112132fc6578254c0ee84015c4b36fa386b9 (patch) | |
| tree | 1577cb5221db2fa6ae74843e9ad1062fecffb799 | |
| download | backomp-1cf9112132fc6578254c0ee84015c4b36fa386b9.tar.gz backomp-1cf9112132fc6578254c0ee84015c4b36fa386b9.tar.xz | |
initial import
| -rwxr-xr-x | backomp | 80 | 
1 files changed, 80 insertions, 0 deletions
| @@ -0,0 +1,80 @@ +#!/usr/bin/env bash + +set -e + +! read -rd '' FILTER_AWK <<'EOF' +function flr(n, s) { return int(n / s) * s } + +{ +	t = mktime(gensub(/(.*\/|^)(.+)-(..)-(..)-(..)(..)(..)/, +		"\\2 \\3 \\4 \\5 \\6 \\7", 1), 1) + +	h = flr(t, 60*60) +	d = flr(t, 24*60*60) +	m = mktime(strftime("%Y %m", t, 1) " 01 00 00 00", 1) +	w = m + flr(t - m, 7*24*60*60) +} + +h in hkeep || hc++ < 24 { hkeep[h] = $1 } +d in dkeep || dc++ < 7 { dkeep[d] = $1 } +w in wkeep || wc++ < 4 { wkeep[w] = $1 } +{ mkeep[m] = $1 } + +END { +	for (i in hkeep) keep[hkeep[i]]++ +	for (i in dkeep) keep[dkeep[i]]++ +	for (i in wkeep) keep[wkeep[i]]++ +	for (i in mkeep) keep[mkeep[i]]++ + +	asorti(keep) +	for (i in keep) print keep[i] +} +EOF + +run() { +	echo "* ${@}" +	"${@}" +} + +backup() { +	dest_dir="${1}" +	src_path="${2}" + +	[[ "$((dcount++))" -ne 0 ]] && echo +	echo "[${dcount}] ${src_path} => ${dest_dir}" +	mapfile -t snaps < <(shopt -s nullglob; +		printf '%s\n' "${dest_dir}/"* | sort -r | head -c -1) + +	dest_path="${dest_dir}/$(date -u '+%Y-%m-%d-%H%M%S')" +	run rsync -ac --mkpath ${snaps[0]:+"--link-dest=${snaps[0]}"} \ +		"${src_path}" "${dest_path}" +	snaps=("${dest_path}" "${snaps[@]}") + +	mapfile -t keep < <( +		awk "${FILTER_AWK}" < <(printf '%s\n' "${snaps[@]}")) +	if [[ -z "${keep}" ]]; then +		echo "WARNING: dirs to keep shouldn't be empty; skipping" >&2 +		return +	fi + +	for ((i = ${#snaps[@]} - 1, ki = 0; i >= 0; --i)); do +		if [[ "${snaps[i]}" == "${keep[ki]}" ]]; then +			((++ki)) +		else +			run rm -r "${snaps[i]}" +		fi +	done + +	printf 'kept %s\n' "${keep[@]}" +} + +while IFS='=' read -r f1 f2; do +	[[ -z "${f1}" ]] && continue + +	if [[ "${f1}" =~ ^\[(.*)]$ ]]; then +		base_path="${BASH_REMATCH[1]}" +		continue +	fi + +	backup "${base_path}/${f1}" "${f2}" +done < "${1}" | 
