LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org
User Name
Password

Notices


By ghostdog74 at 2008-09-13 21:50
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)
    }
    
}'
Usage:

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"


  



All times are GMT -5. The time now is 07:07 PM.

Main Menu
Advertisement
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration