#!/bin/bash set -eu save_directory="" saveset_pattern="" filename="" function usage { retval="$1" case "$retval" in 0) ;; *) exec 1>&2 ;; esac echo "Usage: $0 --save-directory /backshift-production/save-directory --saveset-pattern '^.*hostname.*subset.*$' --filename /f/n" echo echo 'Extract all versions of a file in the save directory, for a given saveset pattern' # shellcheck disable=SC2016 echo 'Extracts all files to ./extracts/$backup_id/$directory/$(basename $filename)' exit "$retval" } while [ "$#" -ge 1 ] do case "$1" in --save-directory) save_directory="$2" shift ;; --saveset-pattern) saveset_pattern="$2" shift ;; --filename) filename="$2" shift ;; --help|-h) usage 0 ;; *) echo "$0: unrecognized option: $1" 1>&2 usage 1 ;; esac shift done preflight_check_ok=True case "$save_directory" in "") echo "$0: --save-directory is a required option" 1>&2 preflight_check_ok=False ;; esac case "$saveset_pattern" in "") echo "$0: --saveset-pattern is a required option" 1>&2 preflight_check_ok=False ;; esac case "$filename" in "") echo "$0: --filename is a required option" 1>&2 preflight_check_ok=False ;; /*) # Good, it starts with a slash ;; *) echo "$0: --filename must specify an absolute path" 1>&2 preflight_check_ok=False ;; esac case "$preflight_check_ok" in True) ;; False) echo "$0: One or more items in preflight check failed" 1>&2 exit 1 ;; *) echo "$0: Internal error: \$preflight_check_ok has a strange value: $preflight_check_ok" 1>&2 exit 1 ;; esac absolute_directory=$(dirname "$filename") # Make $filename relative # shellcheck disable=SC2001 filename=$(echo "$filename" | sed 's#^/##') # And get the directory that contains it # relative_directory=$(dirname "$filename") function backup_ids { # Note that this will only list completed savesets. backshift --save-directory "$save_directory" --list-backups | grep -E "$saveset_pattern" | awk '$4 != "None" { print $1 }' } mkdir -p extracts cd extracts echo "Obtaining list of backup ids" for backup_id in $(backup_ids) do export backup_id echo Checking "$backup_id" ( set -eu mkdir -p "$backup_id" cd "$backup_id" backshift \ --save-directory "$save_directory" \ --backup-id "$backup_id" \ --produce-tar \ --starting-directory "$absolute_directory" \ --nonrecursive \ | tar xvfp - "$filename" \ || true ) done echo echo 'Now consider running something like:' echo 'find extracts -type f -print0 | equivs3e -v -0 --one-per-duplicate'