Mass File Renamer: Changing Cases(Upper/Lower)
Posted 09-13-2008 at 10:50 PM by ghostdog74
Code:
#!/bin/bash
## Change file names into uppper/lower case, or by position.
NO_ARGS=0
E_OPTERROR=65
DEBUG=0
UPPER=0
FNAME="f"
maxdepth=1
directory=`pwd`
set -o noglob
#---- Functions ------------#
usage() {
printf "Usage: `basename $0` [-D directory] [-M depth] [-U ] [-p pattern] [-c position ][-d] [-X] [filename(s)]\n"
cat << EOF
-D : starting directory. Default=current directory
-M : max depth to recurse subdirectories (default=1), eg 1,2
-U : Change all letters to upper case. Default: change to all lower case
-c position : Change character at position to upper or lower (-U or -L)
-p pattern: Change the word matched by pattern to upper/lower case
-d : Debugging mode. Used to list all files to be changed, without changes taking effect
-X : Only check directory names, not file names
filename(s) : file names eg "*.txt". If omitted, default to all files. Use quotes.
Example:
1) -U -p file "*.txt" ===> change all name of text files with pattern "file" to upper case.
2) -U -c 10 "*.txt" ===> change the 10th character to upper case
3) -c 2 "*FILE*" ===> change the 2nd character to lower case for all files with pattern "FILE" in file name.
EOF
}
#----------------------------#
if [ $# -eq "$NO_ARGS" ] # Script invoked with no command-line args?
then
usage
exit $E_OPTERROR # Exit and explain usage, if no argument(s) given.
fi
while getopts ":D:s:e:M:p:c:dUX" Option
do
case $Option in
D ) directory=$OPTARG
;;
d ) DEBUG=1 ;;
U ) UPPER=1;;
c ) position=$OPTARG
case ${position} in
0 | *[a-z]*) position=1;;
esac
;;
p ) pattern=$OPTARG
[ -z "${pattern}" ] && pattern=".*"
;;
M ) maxdepth=$OPTARG
case ${maxdepth} in
0 | *[a-z]*|"") maxdepth=1;;
esac
;;
X ) FNAME="d";;
* ) echo "Unimplemented option chosen."
exit;;
esac
done
shift $(($OPTIND - 1))
# get last argument
argument=$#
if [ $argument -eq 0 ];then
ext="*"
else
ext=$(eval echo \"\${${argument}}\")
fi
find "${directory}" -maxdepth "${maxdepth}" -type "${FNAME}" -name "$ext" -printf "%f:%h:%p\n" | \
awk -F":" -v pattern="${pattern}" -v debug="$DEBUG" -v upper=${UPPER} -v position="${position}" 'BEGIN{
q="\042"
}
$1 ~ pattern{
if ( upper ) {
if ( position>0 ) {
#change only positional characters to upper
newname = substr($1,1,position-1) toupper(substr($1,position,1)) substr($1,position+1)
}else if ( int(position)<0 ) {
#change to upper from the back
newname = substr($1,1,length($1)+position) toupper(substr($1,length($1)+position+1))
}else if ( !position ) {
# change all characters to upper
if ( pattern == ".*" ) {
newname = toupper($1)
}else {
newname=$1
gsub(pattern,toupper(pattern),newname)
}
}
}else if (!upper) {
if ( position>0 ) {
# change only positional characters to lower
newname = substr($1,1,position-1) tolower(substr($1,position,1)) substr($1,position+1)
}else if ( int(position)<0 ){
#change to lower from the back
newname = substr($1,1,length($1)+position) tolower(substr($1,length($1)+position+1))
}else if (!position) {
# change all characters to lower
if ( pattern == ".*" ) {
newname = tolower($1)
}else {
newname=$1
gsub(pattern,tolower(pattern),newname)
}
}
}
if ( newname == $1 ) {next}
if ( debug) {
print "mv -u " q $3 q " "q $2 "/" newname q
}else {
cmd = "mv -u " q $3 q " "q $2 "/" newname q
system(cmd)
}
}'
The script makes use of GNU find/awk. Maximum depth value passed to "find" is set to default 1 level. Issue -M <level> to recurse more than 1 level of subdirectories. File types is set to search for files by default. Issue -X to search for directory names. If -D <directory> is omitted, the script searches from current working directory onwards.
Use -U ( or omit for lower case) for changing to upper case.
# Execute the script name without any arguments to show help.
> ./script.sh
# To see results before making actual changes, use the -d switch.
> ./script.sh -D /path/1 -U -p image -d "*.txt"
# To search text files in directories for 2 levels and change word "file" in their file names to Upper case
> ./script.sh -D /path/1 -M 2 -U -p "file" -d "*.txt"
# To search text files in current directory and change word "FILE" in their file names to lower case
> ./script.sh -p "FILE" "*.txt"
# To search text files in current directory and change the first character of each text file name to upper case
> ./script.sh -U -c 1 "*.txt"
# To search text files in current directory and change the last 2nd character onwards of each text file name to lower case
> ./script.sh -c -2 "*.txt"
# To rename all file names to capital letters
> ./script.sh -U -p ".*" "*.txt"
# To rename all file names to lower case letters
> ./script.sh -p ".*" "*.txt"









