#!/bin/bash function helpexit() { echo 'Create or append md5sum list of files Usage: md5sum-update [-r] [-f list_name] [[files to check]] -r recursive -f list_name is md5sums.txt by default If files to check omitted, list files in current folder Check files with "md5sum -c md5sums.txt" To update hashes, simply delete the md5sums file. ' exit } recursive=0 list_name="md5sums.txt" paths=() for ((i=1; i<=${#@}; i++)) { j=$(( i + 1 )) [[ "${!i}" = "-h" ]] && helpexit [[ "${!i}" = "--help" ]] && helpexit [[ "${!i}" = "-r" ]] && { recursive=1; continue; } [[ "${!i}" = "-f" ]] && { list_name="${!j}"; i=$(( $i + 1 )); continue; } paths+=("${!i}") } if [[ ${#paths[@]} -eq 0 ]]; then paths+=(".") fi which pv &>/dev/null && PVBIN=$( which pv ) set -e echo "Updating: $list_name" test -f "$list_name" || touch "$list_name" updates_done=0 _update() { if [ "$1" = "$list_name" ]; then return fi if [[ -L "$1" ]]; then echo "$1 is a symlink" return fi if test -d "$1"; then echo "$1 is a directory" return fi if test -f "$1"; then if awk '{ print substr($0,35) }' "$list_name" | grep -qFx "$1"; then echo "Exists: $1" else echo "New: $1" size=$( stat -c %s "$1" ) if [[ $size -gt 100000000 ]] && [[ -n "$PVBIN" ]]; then # Use pv is size > 100MB sum=$( $PVBIN "$1" | md5sum | awk '{ print $1 }' ) printf "%s %s\n" "$sum" "$1" >> "$list_name" else md5sum "$1" >> "$list_name" fi updates_done=1 fi fi } shopt -s globstar shopt -s nullglob for ((i=0; i<=${#paths[@]}; i++)) { if [[ -d "${paths[$i]}" ]]; then pathname="${paths[$i]}" pathname="${pathname%%/}" if [[ "$recursive" -eq 1 ]]; then for file in "${pathname}"/**; do file="${file#./}" _update "$file" done else for file in "${pathname}"/*; do file="${file#./}" _update "$file" done fi fi if [[ -f "${paths[$i]}" ]]; then file="${paths[$i]}" file="${file#./}" _update "$file" fi } if [[ $updates_done -eq 1 ]]; then sort -k 2 -o "$list_name" "$list_name" fi