#!/bin/sh : ; exec klone $0 "$@" ; The above line finds the klone executable in the $PATH ;;Skeleton of a typical klone script (setq args (getopts "USAGE: %0 [options] files... Converts files and dirs to lowercase. Recurse in dirs Aborts in error if it cannot rename. " ("-u" () upper "converts to upper case instead") ("-%" () percent "converts %xx to _ in names instead of changing cases") ("-s" () spaces "converts spaces to _ in names instead of changing cases") ("-n" () nothing "do not perform renames") ("-v" () verbose "verbose operation") ("-w" () nocase "to use on case-insensitive (windows) filesystems Put this option in case of errors like \"file identicals\"") ("-nr" () norecurse "do not recurse in dirs") ("-c" () caps "Puts into Caps mode: transforms foo.bar, FOO_BAR, foo bar, foo-bar, into FooBar") ("-debug" () enter-debugger-on-error "enter klone debugger on error" :hidden t) ("-stackdump" () stackdump-on-error "verbose stack dump on error" :hidden t) )) (if (not args) (setq args '("."))) (if enter-debugger-on-error (kdb t)) (if stackdump-on-error (stack-dump-on-error t)) (defun do-file (file rest &aux (lfile (convfunc file)) ) (if (/= "" file) (progn (dolist (f rest) (if (= lfile (convfunc f)) (abort "ERROR: files %0 and %1 exist together in %2" file f *current-directory* ))) (if (/= file lfile) (progn (verbose? " %0 ==> %1" file lfile) (if (not nothing) (if (not (rename-file file lfile)) (abort "ERROR: moving %0 into %1 in %2 failed" file lfile *current-directory* )))))))) (defun do-dir (dir &aux (*current-directory* dir) (filelist (directory)) (file (getn filelist 0)) ) (delete filelist 0) (while file (if (and (= 'directory (file-type file)) (not norecurse)) (do-dir file) ) (do-file file filelist) (setq file (getn filelist 0)) (setq filelist (subseq filelist 1)) ) ) (defun rename-file (f1 f2) (if nocase (and (= 0 (wait (system (list "mv" f1 "________.___")))) (= 0 (wait (system (list "mv" "________.___" f2)))) ) (= 0 (wait (system (list "mv" f1 f2)))) ) ) (defun abort (&rest args) (apply print-format (+ (list *standard-error*) args)) (write-line "ABORTING OPERATION NOW\n" *standard-error*) (exit 1) ) (defun filepart (file &aux (re (regcomp "^(.*)[/]([^/]+)$")) ) (if (regexec re file) (regsub re 2) file) ) (defun dirpart (file &aux (re (regcomp "^(.*)[/]([^/]+)$")) ) (if (regexec re file) (regsub re 1) ".") ) (setq percent-re (regcomp "%[0-9a-fA-F][0-9a-fA-F]")) (defun percent-conv (s &aux (res (copy s))) (replace-string res percent-re "_" :all t :quote t) res ) (setq spaces-re (regcomp " ")) (defun spaces-conv (s &aux (res (copy s))) (replace-string res spaces-re "_" :all t :quote t) res ) (defun caps-conv (s &aux (res (copy ""))) (doregexp (re "([^ ._-])([^ ._-]*)" s) (nconc res (toupper (re 1)) (tolower (re 2))) ) res ) (defun main (&aux ) (setq convfunc (if percent percent-conv spaces spaces-conv caps caps-conv t (if upper toupper tolower) )) (dolist (file args) (if (and (not norecurse) (= 'directory (file-type file))) (do-dir file) ) (with (*current-directory* (dirpart file) fl (directory) ) (delete-item fl (filepart file)) (do-file (filepart file) fl) )) ) (main) ;;; EMACS MODES ;;; Local Variables: *** ;;; mode:lisp *** ;;; End: ***