#! /usr/bin/racket #| | Copyright © 2013 Kenneth Graunke | | Permission is hereby granted, free of charge, to any person obtaining a | copy of this software and associated documentation files (the "Software"), | to deal in the Software without restriction, including without limitation | the rights to use, copy, modify, merge, publish, distribute, sublicense, | and/or sell copies of the Software, and to permit persons to whom the | Software is furnished to do so, subject to the following conditions: | | The above copyright notice and this permission notice (including the next | paragraph) shall be included in all copies or substantial portions of the | Software. | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | DEALINGS IN THE SOFTWARE. |# #lang racket (require file/sha1) (require racket/set) ; [filename] ; [(filename, sha1sum)] ; [ ; filename -> (sha1sum . filename) (define (make-sha1-pair filename) (cons (call-with-input-file filename sha1) filename)) ; Convert an association list containing duplicate keys to a ; hash table mapping from keys -> list of values. ; ; For example: ; '((a . "apple") (b . "banana") (b . "bonus")) ; becomes: ; #hash((b . ("bonus banana")) (a . ("apple"))) (define (bagify assocs) (foldl (lambda (pair ht) (hash-update ht (car pair) (curry cons (cdr pair)) '())) #hash() assocs)) ; list -> bag (define (make-sha1bag files) (hash->list (bagify (map make-sha1-pair files)))) ; True if (length x) > 2 (define (two-or-more? x) (and (not (empty? x)) (not (empty? (cdr x))))) ; bag -> (define files (current-command-line-arguments)) ;(define files '#("/tmp/hi" "/tmp/there" "/tmp/hello")) (define sha1bag (make-sha1bag (vector->list files))) (define dups (filter two-or-more? (map cdr sha1bag))) (for-each (lambda (x) (display "Duplicates:") (newline) (for-each (lambda (x) (display "- ") (display x) (newline)) x) (newline)) dups) (for-each (lambda (x) (display "rm ") (for-each (lambda (x) (display x) (display " ")) (cdr x)) (newline)) dups)