diff --git a/notwa-util/dedupe b/notwa-util/dedupe index 62da551..9d58899 100755 --- a/notwa-util/dedupe +++ b/notwa-util/dedupe @@ -1,16 +1,41 @@ #!/usr/bin/env sh +# Copyright (C) 2022 Connor Olding + +usage='dedupe [OPTION...] {SOURCE} {TARGET} [FILE...] +Copy files, recursively, from the source directory to the target directory, +creating hard (or soft) links to any earlier file containing the same data. +Optional file arguments allow for finer control of the order of files seen. + + --help display this help and exit + --soft create soft links (default) + --hard create hard links + +This software is provided WITHOUT WARRANTY under the terms of the ISC license. +' + read -r program <<'EOF' BEGIN{if(!D){print U;exit 64}E=(Q="'")"\"'\""Q;H=(G=".")(F="/");I=" -- "Q;J="[^/]*/";sub(F"?$",F,D)gsub(Q,E,D)}function C(x){if(X=system(x))exit X}{if((p=$2)==B){print V;exit 65}for(r=z=i=d=B;d!=!i;i++){b=a=p;d=sub("/.*",B,a);sub(J,B,p);if(a==G G)e=!sub(J,B,z);else z=a==G?z:b!=a?z a F:z a;if(e||!i&&!a){print W;exit 65}}P=p=!z?H:z;if((o=O[$1])==p)next;gsub(Q,E,P);M=m=D P;gsub("/[^/]+$",B,M);if(!u[M]++)C("mkdir -p"I M Q);if(o){T=split(o,t,F);S=split(p,s,F);for(i=1;t[i]==s[i];i++);for(j=i;j&2 dedupe "$*" ;} \ - && { [ -d /tmp ] || { complain "/tmp must be mounted"; exit 72 ;} ;} \ - && h=0 && { [ "$1" != --hard ] || shift && h=1 ;} \ - && cd "$1" && shift && D="$1" && shift && t="$(mktemp)" \ + && die() { printf '\033[1mdedupe:\033[m %s\n' >&2 "$2"; exit "$1" ;} \ + && while o="${1#-}" && [ "${#o}" != "${#1}" ] && shift \ + ;do case "$o" in \ + (-) break ;; \ + (-help) printf '\033[1mUsage:\033[m %s' "$usage"; exit ;; \ + (-soft) h=0 ;; \ + (-hard) h=1 ;; \ + (-*) die 64 "unknown long option: -$o" ;; \ + (*) die 64 "unknown short option: -${o%"${o#?}"}" ;; \ + esac;done \ + && { [ -d /tmp ] || die 72 "/tmp must be mounted" ;} \ + && { [ $# -ge 2 ] || die 64 'expected at least 2 arguments' ;} \ + && cd -- "$1" && shift && D="$1" && shift && t="$(mktemp)" \ && { [ $# -eq 0 ] || sha256sum >"$t" "$@" ;} \ - && find ! -type d -exec sha256sum {} + >>"$t~" \ + && find ! -type d ! -type s -exec sha256sum -- {} + >>"$t~" \ && sort -k2, <"$t~" >>"$t" \ && awk -v D="$D" -v h="$h" -F' ' "$program" <"$t" \ ;