🔍
Code Snippet — July 11, 2026Find Duplicate Files by Content Hash
Pure Bash, zero dependencies. Pre-filters by size, groups by md5/sha256, shows exact disk waste:
#!/usr/bin/env bash
set -euo pipefail
DIR="." DEL=false DRY=false HASH_ALG="md5"
while [[ $# -gt 0 ]]; do case "$1" in
--delete) DEL=true;; --dry-run) DRY=true;; --hash) HASH_ALG="$2";shift;;
*) DIR="$1";; esac; shift; done
HC=$(command -v md5sum &>/dev/null && echo md5sum || echo "md5 -r")
declare -A SF SC HF
while IFS= read -r -d '' f; do sz=$(stat -c%s "$f")
SF[$sz]+=$'\n'"$f"; SC[$sz]=$(( ${SC[$sz]:-0}+1 ))
done < <(find "$DIR" -type f -print0)
for sz in "${!SC[@]}"; do [[ "${SC[$sz]}" -lt 2 ]] && continue
while read -r f; do [[ -z "$f" ]] && continue
h=$($HC "$f"|cut -d' ' -f1); HF[$h]+=$'\n'"$f"
done <<< "${SF[$sz]}"; done
for h in "${!HF[@]}"; do files="${HF[$h]}"; n=$(echo "$files"|wc -l)
[[ $n -lt 2 ]] && continue; echo "Dup: $n files (hash: ${h:0:12}...)"
i=0; while read -r f; do i=$((i+1))
[[ $i -eq 1 ]] && echo " KEEP: $f" && continue
[[ "$DEL" == true ]] && echo " DEL: $f" && rm -f "$f"
[[ "$DRY" == true ]] && echo " WOULD DEL: $f" && continue
echo " DUP: $f"; done <<< "$files"; done
Usage:./find-dupes.sh ~/Downloads --dry-run./find-dupes.sh /var/cache --delete./find-dupes.sh ./data --hash sha256💡 Add to ~/.local/bin/find-dupes. Groups by size first (skips hashing unique files), auto-detects Linux/macOS, shows MB wasted.