#!/bin/bash VERSION="20170907" function helpexit() { BS=$( basename "$0" ) echo "Archive the subfolders of the current directory, version: $VERSION" echo "Requires pv, tar and python" echo "Usage: $BS [-z/-n/--rm] [folder name(s)]" echo " -z Compress." echo " -n No compression. [default]" echo " --nl Do not store a separate file list." echo " --rm Remove source folders after archival." echo " folder name: If given, archive only the named folder(s)." echo " If not, for loop over all folders in the current directory." exit } function listfolders() { find "$@" -mindepth $DEPTH -maxdepth $DEPTH -type d | sort } function count_size() { cat - | python -c "import sys def sizeof_fmt(num, suffix='B'): for unit in ['','K','M','G','T','P','E','Z']: if num < 1024.0: return '%3.1f%s%s' % (num, unit, suffix) num /= 1024.0 return '%.1f%s%s' % (num, 'Y', suffix) sum=0 try: for line in sys.stdin: sum += int(line) sys.stderr.write('\r%s: %s \r'%(sys.argv[1],sizeof_fmt(sum))) sys.stderr.flush() except KeyboardInterrupt: sys.stdout.flush() sys.stderr.flush() pass print(sum) " "$1" } function exitokay() { [[ "$REMOVE" -eq 1 ]] && { exit; } echo -ne "\n${G}If all looks okay, delete source folders with: ${Z}# rm -r " for folder in "${REALFOLDERS[@]}"; do echo -n "'$folder' "; done echo '' exit } _qCol(){ true; } # incase qolop missing . qolop &>/dev/null Z=$( _qCol z ) #reset color S=$( _qCol S ) #Bold R=$( _qCol z R ) #Red G=$( _qCol z g ) #green Y=$( _qCol z Y ) #Yellow NOCOMPRESSION=1 COMPRESSION=0 SUFFIX=tar DEPTH=1 FOLDERS=( ) REMOVE=0 KEEP_LIST=1 for ((i=1; i<=${#@}; i++)) { [[ "${!i}" = "-h" ]] && helpexit [[ "${!i}" = "--help" ]] && helpexit [[ "${!i}" = "-n" ]] && { continue; } # obsolete behaviour [[ "${!i}" = "-z" ]] && { COMPRESSION=1; NOCOMPRESSION=0; COMPRESSCMD="| gzip"; SUFFIX=tgz; continue; } [[ "${!i}" = "--nl" ]] && { KEEP_LIST=0; continue; } [[ "${!i}" = "--rm" ]] && { REMOVE=1; continue; } [[ "${!i}" = "-"* ]] && helpexit FOLDERS+=( "${!i%/}" ) DEPTH=0 } [[ ${#FOLDERS[@]} -eq 0 ]] && FOLDERS+=( "." ) which pv &>/dev/null || { echo pv command missing; exit 1; } export IFS=$'\n' REALFOLDERS=( $( listfolders "${FOLDERS[@]}" ) ) echo $R'Existing files will be overwritten!'$Z [[ "$REMOVE" -eq 1 ]] && echo 'Source folders will be deleted!' [[ "$KEEP_LIST" -eq 0 ]] && echo 'File list will be removed.' echo -n $S"Archive the following folders " [[ "$NOCOMPRESSION" -eq 1 ]] && { echo -n without compression; } || { [[ "$COMPRESSION" -eq 1 ]] && echo -n with gzip compression } echo ':'$Z for folder in "${REALFOLDERS[@]}"; do echo -n "'$folder', "; done | sed -e "s/..$//" printf "\n$S to quit$Z\n" read foo set -o pipefail for d in "${REALFOLDERS[@]}"; do printf "$d" SIZE=$( find "$d" -type f -printf %s"\n" | count_size "$d" ) printf "\n" eval "tar cvv --index-file=\"$d.${SUFFIX}.lst\" \"$d\" | \ pv -s \"$SIZE\" $COMPRESSCMD > \"$d.${SUFFIX}\"" && { # tar exists okay if [ "$KEEP_LIST" -eq 0 ]; then rm -f "$d.${SUFFIX}.lst" fi if [ "$REMOVE" -eq 1 ]; then printf "${Y}Removing folder $d$Z\n" which rm-progress &> /dev/null && rm-progress -f "$d" [[ -d "$d" ]] && rm -r "$d" fi } done exitokay