sed: Rename files to lower case
1
1 7.4 Rename Files to Lower Case
1 ==============================
1
1 This is a pretty strange use of 'sed'. We transform text, and transform
1 it to be shell commands, then just feed them to shell. Don't worry,
1 even worse hacks are done when using 'sed'; I have seen a script
1 converting the output of 'date' into a 'bc' program!
1
1 The main body of this is the 'sed' script, which remaps the name from
1 lower to upper (or vice-versa) and even checks out if the remapped name
1 is the same as the original name. Note how the script is parameterized
1 using shell variables and proper quoting.
1
1 #! /bin/sh
1 # rename files to lower/upper case...
1 #
1 # usage:
1 # move-to-lower *
1 # move-to-upper *
1 # or
1 # move-to-lower -R .
1 # move-to-upper -R .
1 #
1
1 help()
1 {
1 cat << eof
1 Usage: $0 [-n] [-r] [-h] files...
1
1 -n do nothing, only see what would be done
1 -R recursive (use find)
1 -h this message
1 files files to remap to lower case
1
1 Examples:
1 $0 -n * (see if everything is ok, then...)
1 $0 *
1
1 $0 -R .
1
1 eof
1 }
1
1 apply_cmd='sh'
1 finder='echo "$@" | tr " " "\n"'
1 files_only=
1
1 while :
1 do
1 case "$1" in
1 -n) apply_cmd='cat' ;;
1 -R) finder='find "$@" -type f';;
1 -h) help ; exit 1 ;;
1 *) break ;;
1 esac
1 shift
1 done
1
1 if [ -z "$1" ]; then
1 echo Usage: $0 [-h] [-n] [-r] files...
1 exit 1
1 fi
1
1 LOWER='abcdefghijklmnopqrstuvwxyz'
1 UPPER='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1
1 case `basename $0` in
1 *upper*) TO=$UPPER; FROM=$LOWER ;;
1 *) FROM=$UPPER; TO=$LOWER ;;
1 esac
1
1 eval $finder | sed -n '
1
1 # remove all trailing slashes
1 s/\/*$//
1
1 # add ./ if there is no path, only a filename
1 /\//! s/^/.\//
1
1 # save path+filename
1 h
1
1 # remove path
1 s/.*\///
1
1 # do conversion only on filename
1 y/'$FROM'/'$TO'/
1
1 # now line contains original path+file, while
1 # hold space contains the new filename
1 x
1
1 # add converted file name to line, which now contains
1 # path/file-name\nconverted-file-name
1 G
1
1 # check if converted file name is equal to original file name,
1 # if it is, do not print anything
1 /^.*\/\(.*\)\n\1/b
1
1 # escape special characters for the shell
1 s/["$`\\]/\\&/g
1
1 # now, transform path/fromfile\n, into
1 # mv path/fromfile path/tofile and print it
1 s/^\(.*\/\)\(.*\)\n\(.*\)$/mv "\1\2" "\1\3"/p
1
1 ' | $apply_cmd
1