#!/usr/bin/env zsh emulate -L zsh export LC_ALL=C typeset -F SECONDS AUDIT="$HOME/msd512-audit" DST="/Volumes/photos library iCloud" BUNDLE="$DST/photos-restore.photoslibrary" [[ -s "$AUDIT/worklist.tsv" ]] || { print "FATAL: run phase1 first"; exit 1; } if whence -p b3sum > /dev/null; then HASH=(b3sum); HN=blake3 elif whence -p xxh128sum > /dev/null; then HASH=(xxh128sum); HN=xxh128 else HASH=(shasum -a 256); HN=sha256; fi print "$HN" > "$AUDIT/hash.algo" awk -F'\t' '{print $3}' "$AUDIT/worklist.tsv" | sort -u > "$AUDIT/src.sizes.txt" awk -F'\t' 'NR==FNR{z[$1]=1; next} ($2 in z){print $3}' "$AUDIT/src.sizes.txt" "$AUDIT/dst.manifest.tsv" > "$AUDIT/dst.candidates.txt" t0=$SECONDS tr '\n' '\0' < "$AUDIT/dst.candidates.txt" | xargs -0 -P $(sysctl -n hw.ncpu) -n 32 $HASH 2>> "$AUDIT/phase2.err" > "$AUDIT/dst.hashes.raw" el=$(( SECONDS - t0 + 0.001 )) # normalise " " into hashinbundlepath awk -v B="$BUNDLE" '{h=$1; $1=""; sub(/^[ \t]+/,""); p=$0; printf "%s\t%d\t%s\n", h, (index(p,B)==1)?1:0, p}' "$AUDIT/dst.hashes.raw" > "$AUDIT/dst.hashes.tsv" print "===== PHASE2 =====" printf 'algo=%s candidates=%s hashed=%s elapsed=%.1fs\n' "$HN" "$(wc -l < "$AUDIT/dst.candidates.txt" | tr -d ' ')" "$(wc -l < "$AUDIT/dst.hashes.tsv" | tr -d ' ')" $el awk -F'\t' '{if($2==1)ib++; else lo++} END{printf "in-bundle=%d loose=%d\n", ib+0, lo+0}' "$AUDIT/dst.hashes.tsv" head -4 "$AUDIT/phase2.err" 2>/dev/null