35 lines
858 B
Bash
35 lines
858 B
Bash
#!/usr/bin/env bash
|
|
# usage: smart-cp SRC DST
|
|
set -euo pipefail
|
|
|
|
src=$1
|
|
dst=$2
|
|
|
|
find "$src" -type f -print0 | while IFS= read -r -d '' f; do
|
|
rel=${f#"$src"/}
|
|
target=$dst/$rel
|
|
mkdir -p "$(dirname "$target")"
|
|
|
|
if [[ ! -e $target ]]; then
|
|
cp -p "$f" "$target"
|
|
continue
|
|
fi
|
|
|
|
src_size=$(stat -c%s "$f")
|
|
dst_size=$(stat -c%s "$target")
|
|
|
|
if (( src_size == dst_size )); then
|
|
continue # same size — leave it alone
|
|
fi
|
|
|
|
printf '%s differs (src=%d, dst=%d) — [o]verwrite/[s]kip/[d]iff/[q]uit? ' \
|
|
"$rel" "$src_size" "$dst_size" >&2
|
|
read -r choice </dev/tty
|
|
case $choice in
|
|
o|O) cp -p "$f" "$target" ;;
|
|
s|S) ;;
|
|
d|D) diff "$target" "$f" || true; exec "$0" "$src" "$dst" ;; # crude: restart
|
|
q|Q) exit 0 ;;
|
|
*) echo "skipping" >&2 ;;
|
|
esac
|
|
done
|