#!/bin/sh # mklowercase - change all filenames to lowercase recursively from "." down. # Will prompt if there's an existing file of that name (mv -i) # Presumes that filenames don't include newline or tab. # It _CAN_ handle files with spaces, initial dash, and so on, because # "find" prefixes everything with the current directory ("." in this case). # # It could be modified to handle newline/tab by changing the loop to # find . -depth -print0 | # while IFS="" read -r -d '' file ; do ... # but this requires non-standard GNU extensions to find and bash, # as well as being far uglier/more complicated. Also, if "mv" is implemented # as required by the Single Unix Standard, then the "mv -i" will # fail badly if it tries to rename a file into an existing name. # That's because when it tries to get an answer, it will send a prompt to # stderr, but it will expect a RESPONSE from stdin... and yet, stdin # is where it gets the list of filenames!! # What you REALLY need to do is forbid newline/tab from occurring in filenames. # See: http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html # This complies with Single Unix Specification version 3. # Really really old System V systems will need "tr" changed slightly. set -eu IFS=`printf '\n\t'` for file in `find . -depth` ; do [ "." = "$file" ] && continue # Skip "." entry. dir=`dirname "$file"` base=`basename "$file"` oldname="$dir/$base" newbase=`printf "%s" "$base" | tr A-Z a-z` newname="$dir/$newbase" if [ "$oldname" != "$newname" ] ; then mv -i "$file" "$newname" fi done