#lang scheme (define +size-table+ #("" "Ki" "Mi" "Gi" "Ti" "Ei" "Pi" "Zi" "Yi")) (define (size->size-with-unit size) (let ((log (truncate (/ (log size) (log 1024))))) (values (/ size (expt 1024 log)) (vector-ref +size-table+ (inexact->exact log))))) (define (pad-string desired-length string) (let ((diff (- desired-length (string-length string)))) (format "~A~A" (make-string (max 0 diff) #\Space) string))) (define (main args) (let-values (((process stdout stdin _) (apply subprocess #f #f (current-error-port) "/usr/bin/du" args))) (let* ((sizes-and-files (for/list ((line (in-lines stdout))) (let ((in (open-input-string line))) (cons (read in) (begin (read-char in) (read-line in)))))) (sorted-sizes-and-files (sort sizes-and-files < #:key car))) (for-each (lambda (pair) (match pair ((cons size file) (let-values (((size-in-units unit) (size->size-with-unit (* size 1024)))) (printf "~A ~AB ~A~%" (pad-string 5 (real->decimal-string size-in-units 1)) unit file))))) sorted-sizes-and-files)) (close-output-port stdin) (close-input-port stdout))) (main (vector->list (current-command-line-arguments)))