#!/bin/sh # SPDX-License-Identifier: GPL-2.0 # # Deduplicate files in a given destdir # err() { echo "ERROR: $*" exit 1 } verbose=: destdir= while test $# -gt 0; do case $1 in -v | --verbose) verbose=echo shift ;; *) if test -n "$destdir"; then err "unknown command-line options: $*" fi destdir="$1" shift ;; esac done if test -z "$destdir"; then err "destination directory was not specified." fi if ! test -d "$destdir"; then err "provided directory does not exist." fi if ! command -v rdfind >/dev/null; then err "rdfind is not installed." fi $verbose "Finding duplicate files" rdfind -makesymlinks true -makeresultsfile true "$destdir" >/dev/null # --relative is a GNU coreutils ln extension; not available in BusyBox. # Compute the relative path ourselves using a portable shell function. relpath() { # relpath # Prints the relative path from the directory of to . target="$1" link_dir=$(dirname "$2") # Strip common prefix component-by-component. t="$target" b="$link_dir" # Normalise: remove trailing slashes t=${t%/} b=${b%/} # Walk up from b until it is a prefix of t up="" while [ -n "$b" ] && [ "${t#$b/}" = "$t" ] && [ "$t" != "$b" ]; do b=$(dirname "$b") up="../$up" done if [ "$t" = "$b" ]; then # Same directory rel="." else rel="$up${t#$b/}" fi printf '%s\n' "$rel" } grep DUPTYPE_WITHIN_SAME_TREE results.txt \ | grep -o "$destdir[^ ]*" \ | while read -r l; do target=$(realpath "$l") $verbose "Correcting path for $l" rel=$(relpath "$target" "$l") # BusyBox ln uses short flags: -s (symbolic), -f (force) ln -sf "$rel" "$l" done rm results.txt