LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Blogs > ghostdog74
User Name
Password

Notices


Rate this Entry

Mass File Renamer: By Pattern Substitution

Posted 09-13-2008 at 09:37 PM by ghostdog74

Code:
#!/bin/bash
## Change file names with a pattern substitution.
NO_ARGS=0 
E_OPTERROR=65
DEBUG=0
FNAME="f"
maxdepth=1
directory=`pwd`
set -o noglob

#---- Functions ------------#

usage() {
 printf "Usage: `basename $0` [-D directory] [-M depth] [-s pattern_from ] [-e pattern_to ] [-d] [-X] [filename(s)]\n"
 cat << 'EOF'
        -D : starting directory. Default=current directory
        -M : max depth to recurse subdirectories (default=1), eg 1,2
        -s : pattern to change from. Can be simple shell patterns. eg [0-9], [a-z], "pattern1|pattern2".
             To input special characters, eg "[\`&*]",'[`&*]'
        -e : pattern to change to. To rename to null, use "". eg -e ""
        -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        
        Example: -s file -e test -d *.txt ===> change all name of text files 
                 with pattern "file" to "test". eg file_copy.txt will be changed to test_copy.txt
        
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:Xd" Option
do
  case $Option in
    D     ) directory=$OPTARG
            ;;
    s     ) startseq=$OPTARG            
            [ -z "${startseq}" ] && echo "Pattern not specified. Use -s <pattern_from> and -e <pattern_to>" && exit    
            ;;
    e     ) endseq=$OPTARG
            [ -z "${endseq}" ] && endseq=""
            ;;    
    d     ) DEBUG=1 ;;
    X     ) FNAME="d";;
    M     ) maxdepth=$OPTARG
            case ${maxdepth} in
                0 | *[a-z]* |"") maxdepth=1;;   
            esac
            ;;
    *     ) 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 startseq="${startseq}" -v endseq="${endseq}" -v debug="$DEBUG" 'BEGIN{}
$1 ~ startseq{       
    original=$1
    sq="\047"
    q="\042"
    flag=0
    s = gsub (startseq, endseq,$1 )
    if ( startseg ~ /'"\'"'/) { sq="\042" }    
    if ( startseq ~ /[[:punct:]]/ ) { flag=1} #if found special characters/punctuation
    if ( debug) {
        if(flag) { print "mv -u " q $2"/" q sq original sq " "q $2 "/" $1 q  }
        else{   print "mv -u " q $3 q " "q $2 "/" $1 q        }
    }
    else {
         if(flag) { cmd= "mv -u " q $2"/" q sq original sq " "q $2 "/" $1 q }
         else{  cmd = "mv -u " q $3 q " "q $2 "/" $1 q }
         system(cmd)
    }
    
}'
Usage:

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.

# 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 -M 2 -s "from" -e "to" [color=red]-d[/code] "*.txt"

# To rename files with extension ".txt" and word "image" in their file names to "file" and search directories for 2 levels.
> ./script.sh -D /path/1 -M 2 -s "image" -e "file" "*.txt"

# To rename all files in the current directory with word "file" or "image" to "test" without traversing directories
> ./script.sh -s "file|image" -e "test" -d

# To rename all files in current directory with more than 1 numbers to "test".
> ./script.sh -s "[0-9]+" -e "test" -d

# To replace special characters eg ' (single quote), & ,!
> ./script.sh -s "[!]" -e "" -d
Posted in Uncategorized
Views 2900 Comments 0
« Prev     Main     Next »

  



All times are GMT -5. The time now is 08:12 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