LinuxQuestions.org
Have you listened to LQ Radio?
Go Back   LinuxQuestions.org > Blogs > ghostdog74
User Name
Password

Notices

Rate this Entry

Mass File Renamer: By Pattern Substitution

Submit "Mass File Renamer: By Pattern Substitution" to Digg Submit "Mass File Renamer: By Pattern Substitution" to del.icio.us Submit "Mass File Renamer: By Pattern Substitution" to StumbleUpon Submit "Mass File Renamer: By Pattern Substitution" to Google Submit "Mass File Renamer: By Pattern Substitution" to LinuxQuestions.org
Posted 09-13-2008 at 10: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 843 Comments 0 Edit Tags
« Prev     Main     Next »


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

Main Menu
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
RSS2  LQ Podcast
RSS2  LQ Radio
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: @linuxquestions
Open Source Consulting | Domain Registration