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"