← Back to Blog
Code Snippets July 11, 2026

Code Snippet — July 11, 2026 Find Duplicate Files by Content Hash (Ba

🔍 Code Snippet — July 11, 2026

Find Duplicate Files by Content Hash (Bash)

Your ~/Downloads, Docker build contexts, or CI/CD artifact directories accumulate duplicate files taking gigabytes. fdupes and rdfind work but aren't installed everywhere. This pure Bash script uses find + md5sum, pre-filters by size, groups by content hash, shows disk waste, and supports --dry-run or --delete. Zero dependencies.

```bash
#!/usr/bin/env bash
set -euo pipefail

Defaults


DIRECTION="."
MIN_SIZE=""
DRY_RUN=false
DELETE=false
HASH_ALG="md5"
KEEP_COUNT=1

Parse arguments


while [[ $# -gt 0 ]]; do
case "$1" in
--min-size) MIN_SIZE="$2"; shift 2 ;;
--dry-run) DRY_RUN=true; shift ;;
--delete) DELETE=true; shift ;;
--hash) HASH_ALG="$2"; shift 2 ;;
--keep) KEEP_COUNT="$2"; shift 2 ;;
--verbose|-v) VERBOSE=true; shift ;;
) DIRECTION="$1"; shift ;;
esac
done

Auto-detect hash command (Linux/macOS)


if [[ "$HASH_ALG" == "md5" ]]; then
HASH_CMD=$(command -v md5sum &>/dev/null && echo "md5sum" || echo "md5 -r")
else
HASH_CMD=$(command -v sha256sum &>/dev/null && echo "sha256sum" || echo "shasum -a 256")
fi

Convert size to bytes


size_to_bytes() {
local num="${1%%[MmGgKk]
}"
local unit="${1#$num}"
case "$unit" in
''|k|K) echo "$((num 1024))" ;;
m|M) echo "$((num
1024 1024))" ;;
g|G) echo "$((num
1024 1024 1024))" ;;
*) echo "$num" ;;
esac
}

Build find command


FIND_ARGS=("$DIRECTION" -type f -readable)
if [[ -n "$MIN_SIZE" ]]; then
MIN_BYTES=$(size_to_bytes "$MIN_SIZE")
FIND_ARGS+=(-size "+$(( (MIN_BYTES + 511) / 512 ))c")
fi

Step 1: Group files by size (fast pre-filter)


declare -A SIZE_FILES SIZE_COUNT HASH_FILES

while IFS= read -r -d '' filepath; do
fsize=$(stat -c%s "$filepath" 2>/dev/null || stat -f%z "$filepath" 2>/dev/null)
[[ -z "$...