<?xml version="1.0" encoding="ISO-8859-1"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title>LinuxQuestions.org - Blogs - ghostdog74</title>
		<link>http://www.linuxquestions.org/questions/blog.php?u=290378</link>
		<description>LinuxQuestions.org offers a free Linux forum where Linux newbies can ask questions and Linux experts can offer advice. Topics include security, installation, networking and much more.</description>
		<language>en</language>
		<lastBuildDate>Mon, 23 Nov 2009 23:50:46 GMT</lastBuildDate>
		<generator>vBulletin</generator>
		<ttl>60</ttl>
		<image>
			<url>http://e1h7.simplecdn.net/lqcdn/images/questions/images/misc/rss.jpg</url>
			<title>LinuxQuestions.org - Blogs - ghostdog74</title>
			<link>http://www.linuxquestions.org/questions/blog.php?u=290378</link>
		</image>
		<item>
			<title><![CDATA[Simple Mass File Renamer & Deleter [Python]]]></title>
			<link>http://www.linuxquestions.org/questions/blog.php?b=1190</link>
			<pubDate>Wed, 17 Sep 2008 17:01:27 GMT</pubDate>
			<description>I am so bored today, that i started creating a command line batch file renamer, tested on Linux with Python 2.4. 
Some of the simple things it can do...</description>
			<content:encoded><![CDATA[<div>I am so bored today, that i started creating a command line batch file renamer, tested on Linux with Python 2.4.<br />
Some of the simple things it can do is:<br />
1) Change upper case to lower case and vice versa<br />
2) Change file names by pattern substitution<br />
3) Change file names by number sequence <br />
4) Insert pattern in front of files<br />
5) Insert pattern at the end of files.<br />
6) Simple sort by number.<br />
7) Manual revert of changed files.<br />
8) Deletion of files by pattern match only. <br />
9) Ability to recurse directory<br />
10) Inverse match pattern, like grep -v<br />
11) Case sensitivity search<br />
12) Remove string by character positions. eg 0:10 =&gt; remove from start to 10th character.<br />
<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="bbcodeblock" dir="ltr" style="
		margin: 0px;
		margin-right: -99999px;
		padding: 3px;
		border: 1px inset;
		width: 98%;
		height: 498px;
		text-align: left;
		overflow: auto">#!/usr/bin/env python
import sys,os,getopt,glob,string,re,operator,fnmatch,time

################################## FUNCTIONS #################################################
def usage(name):    
    print &quot;&quot;&quot;
    %s
    Mini File Renamer and Deleter v1.0.2 - Copyright 2008
    Author:	ghostdog74 
    
    %s
    usage: %s [-h] [-D dir] [-t f|d ][-[s|p] oldpat] [-e newpat ] [ -i pattern ][ -b patten ] [-d depth] [-Z|-v|-n|-r|-I] [-l] [files] 
    -D      Directory to start rename/delete. Use quotes for directories with spaces 
            If no directory is specified, current working directory is assumed
            Eg: Use -D c:\\test\\  (for Windows, end with trailing back slash)
    -h      Prints help page                
    -t      Type of files. Either files(f) or directories(d). Default is files, so can omit -t f
    -s      Sequence substitution. Specify pattern to be substituted. Must be specified with -e.
    -p      Pattern substitution. Must be specified with -e (pattern to change to)
            eg. 
                1) To change whole jpeg file name to upper case ==&gt; -p &quot;.*&quot; -e &quot;A-Z&quot; &quot;*.jpeg&quot;
                2) To change the word &quot;TEST&quot; to lower case in jpeg file ==&gt; -p &quot;TEST&quot; -e &quot;a-z&quot; &quot;*.jpeg&quot;
                3) To remove all numbers from directory name ==&gt; -p &quot;[0-9]+&quot; -e '' -t d  -l &quot;*&quot; 
                4) To remove first character from file/directory ==&gt;  -p &quot;^.&quot; -e ''  -l &quot;*.jpeg&quot;  
                5) To remove special characters ==&gt;   -p &quot;[\&quot;^']&quot; -e &quot;back&quot; &quot;*&quot;       
                
    -e     * When used with -s, indicates ending sequence pattern. Can include alphanumberic. Must use &quot;:&quot; to specify range             
            Eg  
                1) -s &quot;test&quot; -e &quot;01:10&quot; will replace 'test' in files from '01' to '10'. If more than 1 files with 'test',
                    will go by sequence, ie '02' , '03' etc.
                2) -s &quot;test&quot; -e &quot;###01:11@@@&quot; will replace 'test' from '###01@@@' , followed by '###02@@@' and so on to ###11@@@            
           * When used with -p, indicates pattern to change to. 
           * When used with -c, specify -e &quot;[A-Z]&quot; to change to uppercase, -e &quot;[a-z]&quot; to change to lower case.
           
    -i	    Insert pattern to infront of file name.
    -b      Insert pattern to back of file name.
    -c      Remove characters in file name by position, position index start from 0. Always use -l to verify files to be changed.
            eg 
            1) -c 1 ==&gt; remove 2nd character
            2) -c -1 ===&gt; remove last character.
            3) -c -2: ===&gt; remove from last 2nd character onwards.
            4) -c 3: ==&gt; remove from 4th character onwards
            5) -c 4:10 ==&gt; remove from 5th to 10th character
            6) -c :3 ==&gt; remove from start to 3rd character.
            7) -c 1:3 -e &quot;[A-Z]&quot; ==&gt; change positions specified to uppercase
                                    
    -l      List all files with pattern only. No renaming. Useful for verifying what will be changed.  
    -r      Used alone. Enable restoration of previous commands. eg %s -r            
    -n      Simple Numerical sort. Specify -n to turn numerical sorting on. Only works on files of the same structure.
    -d      # of directories down to do rename (default = 0). ie: Directory depth level
    -I      Case insensitive pattern search. eg  -p &quot;rot&quot; -e &quot;&quot; -I  -l &quot;*.txt&quot;. Find rot,ROT,roT,RoT ..
    -v      Wildcard pattern reversal. eg -v &quot;*.bat&quot; : Files that doesn't end with .bat.
    -Z      Do deletion of files. 
            eg -d 4 -Z &quot;.*01*&quot;  -l -v  &quot;*.txt&quot; ==&gt; delete all files that doesn't end with .txt and with the pattern &quot;01&quot; in the
                                                   file name, 4 levels deep into current directory
   [files]  List of files to be renamed/deleted. Can have wildcards. eg test*.txt
            To specify all files ==&gt; &quot;*&quot;. Will not work if not specified.
    &quot;&quot;&quot; % (&quot;=&quot; *100 , &quot;=&quot; * 100 ,name,name )
     

def pathChecker(path):
    ''' Function to determine correct path or file exists
        and then returns the number of count of the path separator
        as an indicator of the depth of the path.
    '''    
    if os.path.exists(path):
        pathcount=path.count(os.sep) 
        if pathcount &gt; 1:           
            return int(pathcount) , path  , 0
        else:return 1,1,1
    else:
        return 0,0,-1

def combocheck(s,k):
    '''Function to check the options user keyed in against a set of bad options
        Input : s =&gt; bad options
                k =&gt; list of user supplied keys...eg -S -s -N..etc
    '''
    v = len(s); t = 0 ##store lenght of predefined bad options, t=0 to count matched bad ops
    for x in s:        
        if x in k:
            t = t + 1            
    ## if all bad options found            
    if v == t : return True
    else: return False


def doWalk(DIR=None,maxdepth=1,TYPE=&quot;f&quot;,ACTION=&quot;sub&quot;,patold=None,patnew=None,DEBUG=1,INVERSE=0,CASE=1,SORT=0,FileNamesArgs=None):
    ''' Traverse the directory specified until depth level,
        looking for files with the correct patterns and rename them
        accordingly
    '''
    GlobbedTypeList=[]
    AllFilesGlobbed=[]
  
    
    # convert into reg expression syntax in order to search. eg &quot;*.txt&quot; to &quot;.*txt$&quot;
    
    regex = fnmatch.translate(FileNamesArgs)
    reobj = re.compile(regex) 
    for ROOT,DIRECTORY,FILES in os.walk(DIR,True): 
        #do for files less or equal to maxdepth
        if ROOT.count(os.sep)  &lt;= int(maxdepth):                        
            if FileNamesArgs is not None:     
                if INVERSE:            
                    for FI in os.listdir( ROOT ):
                        if not reobj.search(FI):
                            AllFilesGlobbed.append( os.path.join(ROOT,FI ))
                else:
                    try:
                        allfiles = glob.glob(os.path.join(ROOT,FileNamesArgs))
                    except Exception,e:
                        pass
                    else:
                        if allfiles:
                            for found in allfiles:    
                                if found not in AllFilesGlobbed:
                                    AllFilesGlobbed.append(found)
                            
    if TYPE==&quot;d&quot;:                                         
        for dirname in AllFilesGlobbed:
            if os.path.isdir(dirname):
                if not dirname in GlobbedTypeList: 
                    GlobbedTypeList.append([dirname,dirname.count(os.sep)])
    else:
        for filenames in AllFilesGlobbed:
            if os.path.isfile(filenames):
                if not filenames in GlobbedTypeList:                    
                    GlobbedTypeList.append(filenames) 
        if SORT==1:
            GlobbedTypeList = sorted_copy(GlobbedTypeList)
        else:
            GlobbedTypeList=sorted(GlobbedTypeList, key=(operator.itemgetter(0)))
    # do various actions     
    doAction(GlobbedTypeList,TYPE,ACTION,patold,patnew,CASE,SORT,DEBUG)
                
        
       
def brake():
    raw_input(&quot;Enter&quot;)
     
def  clearscreen(rows):
    for i in range(rows): print 
        
def rename(FROM,TO=&quot;&quot;,DEBUG=1):       
    if FROM == TO:return
    if DEBUG==0  :        
        if TO :            
            try:
                os.rename(FROM,TO)
            except Exception,e:
                print &quot;Error : &quot;,e
            else:
                print FROM , &quot; is renamed to &quot;, TO
                # store to restore file. simple mechanism. Use pickle/shelve ??
                open(restorefile,&quot;a&quot;).write(&quot;&quot;&quot;%s,%s\n&quot;&quot;&quot; %( TO,FROM ))
        elif not TO :
            print &quot;Deleting &quot; ,FROM
            if os.path.isdir(FROM):
                try:
                    os.removedirs(FROM) #or use os.rmdir
                except Exception,e:
                    print &quot;Error: &quot;,e
            elif os.path.isfile(FROM):
                try :
                    os.remove(FROM)
                except Exception,e:
                    print &quot;Error: &quot;,e
              
    else:
        
        print &quot;==&gt;&gt;&gt;&gt; &quot;, &quot;[&quot; ,FROM ,&quot;]==&gt;[&quot;,TO,&quot;]&quot;

def changecase(patnew,thefile):
    # if -c and -e option and -e [A-Z] or -e [a-z]
    try:
        foundlowercase = re.findall( &quot;\[a-z\]|a-z&quot; , patnew)[0]                    
    except:
        try:
            founduppercase = re.findall( &quot;\[A-Z\]|A-Z&quot; , patnew)[0]
        except: notfound=1
        else:
            newname = thefile.replace(thefile,thefile.upper())
    else:
        newname = thefile.replace(thefile,thefile.lower())
    
        
def doAction(FILES,TYPE=&quot;d&quot;, ACTION=&quot;sub&quot;, patold=&quot;&quot; ,patnew=&quot;&quot;, CASE=1, SORT=0,DEBUG=1):
    '''Function to do sequence substitution
        Input:  FILES =&gt; A list of globbed files to be processed.
                TYPE =&gt; f = files, d = directories
                patold =&gt; The pattern in the file to be substituted
                patnew =&gt; The new pattern to replace the old
                DEBUG =&gt; 1 : Do a listing only
                            0 : Do substitution, and renaming of files
    '''      
    
    notfound=0 #flag for doing case change.
    if TYPE==&quot;d&quot;:
        # if renaming directories, rename from the last(highest) level. So have to sort according to maxdepth
        FILES=sorted(FILES, key=(operator.itemgetter(1)),reverse=True)

    if CASE == 0:
        patold_re = re.compile(patold,re.IGNORECASE)
    elif CASE:
        patold_re = re.compile(patold)
        
    if ACTION==&quot;seq&quot;:         
        # see if in format 001:020 ...this indicates sequence
        patnew_re =re.compile(&quot;(\w*\d*\D*)(\d+)[:](\d+)(\D*\w*\d*)&quot;)
        seq = patnew_re.findall(patnew)[0]
        startseq=seq[1]; endseq=seq[-2]
        patendseqfront = seq[0]
        patendseqback = seq[-1]
        if endseq and int(endseq) &lt; int(startseq) :
            startseq,endseq = endseq,startseq
        elif endseq and int(startseq) == int(endseq):
            endseq=startseq
        elif endseq ==&quot;&quot;: endseq=len(FILES)
        length_startseq = len(str(startseq))

    for fn in FILES:
        if TYPE==&quot;d&quot;: FN=fn[0]
        elif TYPE==&quot;f&quot;: FN=fn
        thepath , thefile = os.path.split(FN)            
        if ACTION==&quot;insert&quot;:
            if patnew == &quot;front&quot;:
                newname = patold+thefile
            elif patnew == &quot;back&quot;:
                newname = thefile+patold
            rename(FN, os.path.join(thepath,newname),DEBUG )     
        elif ACTION==&quot;char&quot;:
            # find &lt;digit&gt;:&lt;digit&gt;
            patdigit=re.compile(&quot;(-)*(\d*):(-)*(\d*)&quot;)
            b= list(thefile)
            if patnew and re.search( &quot;\[a-z\]|a-z&quot; , patnew) :
                caseflag=1
            elif patnew and re.search( &quot;\[A-Z\]|A-Z&quot; , patnew):
                caseflag=2
            else:caseflag=0
            
            # if single digit                
            if &quot;:&quot; not in patold and ( int(patold) &lt; 0 or patold.isdigit() ) :
                if caseflag==1 :
                    b[int(patold)] = b[int(patold)].lower()
                elif caseflag==2:
                    b[int(patold)] = b[int(patold)].upper()
                else:
                    b.pop( int(patold) )
                newname = ''.join(b)               
            else:
                foundit = patdigit.findall(patold)[0]
                if foundit:
                    first = &quot;&quot;.join(foundit[0:2])
                    second =  &quot;&quot;.join(foundit[2:])
                    if first and not second:    
                    # if range is  eg 1:
                        if caseflag==1:                            
                            newname = thefile[0:int(first)]+thefile[int(first):].lower()
                        elif caseflag==2:
                            newname = thefile[0:int(first)]+thefile[int(first):].upper()
                        else:                      
                            newname = thefile[ : int(first) ]        
                    elif second and not first:  
                    # if range is eg :10
                        if caseflag==1:
                            newname = thefile[:int(second)].lower()+thefile[int(second):]
                        elif caseflag==2:
                            newname = thefile[:int(second)].upper()+thefile[ int(second) :]
                        else:
                            newname = thefile[ int(second) :]                        
                    elif first and second:    
                    # full range eg 4:10
                        if caseflag==1:
                            newname = thefile[0:int(first)]+thefile[int(first):int(second)].lower()+thefile[int(second):]
                        elif caseflag==2:
                            newname = thefile[0:int(first)]+thefile[int(first):int(second)].upper()+thefile[int(second):]
                        else:                          
                            for it in range(int(first),int(second)): b[it]=&quot;&quot; # delete items to null
                            newname = ''.join(b)                        
            rename(FN, os.path.join(thepath,newname) ,DEBUG )
  
  
        elif patold_re.search(thefile)  : 
            if ACTION==&quot;seq&quot;:    
                #string to replace.             
                repl= patendseqfront+str(startseq).zfill(length_startseq)+patendseqback
                newname = re.sub(patold,repl,thefile)    
                rename(FN, os.path.join(thepath,newname),DEBUG )      
                if int(startseq) == int(endseq):
                    print &quot;\n==&gt;Number of files less than ending sequence number...Exiting..&quot;
                    break          
                #increment sequence
                startseq = int(startseq) + 1     
            elif ACTION==&quot;sub&quot;:
                
                #changing case.  changing all filename to upper/lower case.
                try:
                    foundlowercase = re.findall( &quot;\[a-z\]|a-z&quot; , patnew)[0]                    
                except:
                    try:
                        founduppercase = re.findall( &quot;\[A-Z\]|A-Z&quot; , patnew)[0]
                    except: notfound=1
                    else:
                        newname = thefile.replace(thefile,thefile.upper())
                else:
                    newname = thefile.replace(thefile,thefile.lower())
                    
                if notfound:
                    newname = patold_re.sub(patnew,thefile) 
                rename(FN, os.path.join(thepath,newname),DEBUG ) 
            elif ACTION==&quot;delete&quot;:
                rename(FN, None ,DEBUG )
                
# Taken from Python recipe                
def sorted_copy(alist):
    # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52234
    indices = map(_generate_index, alist)
    decorated = zip(indices, alist)
    decorated.sort()
    return [ item for index, item in decorated ]
    
def _generate_index(str):
    &quot;&quot;&quot;
    Splits a string into alpha and numeric elements, which
    is used as an index for sorting&quot;
    &quot;&quot;&quot;
    #
    # the index is built progressively
    # using the _append function
    #
    index = []
    def _append(fragment, alist=index):
        if fragment.isdigit(): fragment = int(fragment)
        alist.append(fragment)

    # initialize loop
    prev_isdigit = str[0].isdigit()
    current_fragment = ''
    # group a string into digit and non-digit parts
    for char in str:
        curr_isdigit = char.isdigit()
        if curr_isdigit == prev_isdigit:
            current_fragment += char
        else:
            _append(current_fragment)
            current_fragment = char
            prev_isdigit = curr_isdigit
    _append(current_fragment)    
    return tuple(index)                

#--------------------------------------END Functions -------------------------#

## these are options not allowed
bad_options = [ ['-s','-p'],
                ['-Z','-p'],['-Z','-s'],['-Z','-c'],
                ['-c','-b'],['-c','-i'],['-c','-p'],['-c','-s'],
                #can add somemore...
              ]
                
################################## END FUNCTIONS ##################################################
    
if __name__ == '__main__':

    basename = os.path.basename(sys.argv[0])
    
    # create restore directory if doesn't exists
    restorepath = &quot;.restore&quot;
    if not os.path.exists(restorepath): os.mkdir(restorepath,777)    
    # design the restoration filename
    TIME=list(time.localtime())
    # get month and day into double digits string
    if len( str(TIME[1]) ) &lt; 2: 
        TIME[1] = &quot;0&quot;+str(TIME[1])
    if len( str(TIME[2]) ) &lt; 2:
        TIME[2] = &quot;0&quot;+str(TIME[2])
    TIME='-'.join(map(str,TIME))
    
    #name of the restore file
    restorefile  = os.path.join( restorepath , TIME+&quot;-&quot;+basename.split(&quot;.&quot;)[0])

    DEBUG=1
    INVERSE=0
    TYPE=&quot;f&quot; #by default search files, not directories
    ACTION=&quot;sub&quot;
    CASE=1 #case sensitive
    SORT=0 # alphabetical sort.
    
    try:
        opts, args = getopt.gnu_getopt (sys.argv[1:], &quot;D:s:e:p:P:d:t:i:b:c:Z:lInvr&quot;)
        if args is None or len(args) &lt;= 0: args = None
        else: 
            function =args[0]
            FileNames=args[-1]
    except Exception:
        
        usage(basename)
        sys.exit(1)
    if opts == []:
        usage(basename)
        sys.exit(1)

    options = dict(opts) ### convert to dict, easier to manipulate..i guess    
    keys = options.keys() ##get keys from options dictionary for checking

    if options.has_key('-h'):
        usage(basename)
        sys.exit()
           
    #restoration key       
    if options.has_key('-r'):            
        h={};rh={}
        print &quot;These are a list of restore files: &quot;
        for num,rfile in enumerate(os.listdir(restorepath)):
            num=num+1
            h[str(num)] = rfile
        h[str(num+1)]=&quot;Exit&quot; #give the last choice
        while 1:       
            for k in sorted(h.keys()):
                print &quot;%s) %s&quot; % ( k,h[k])         
            choice = raw_input(&quot;Enter your choice( eg 0,1 ) to view: &quot;)
            try :
                int (choice)
            except:
                print &quot;Choose again&quot;
            else:
                ofilename = h[choice]
                if ofilename == &quot;Exit&quot;: sys.exit()
                print &quot;0o0o0o0 ... opening %s ..... 0o0o0o0o &quot;% ofilename
                for n,olines in enumerate(open( os.path.join(restorepath,ofilename))):
                    From,To=olines.strip().split(&quot;,&quot;)
                    n=n+1
                    rh[n] = [From,To]
                rh[n+1]=[&quot;All&quot;,&quot;Original&quot;] 
                while 1:
                    for k in sorted(rh.keys()):
                        print &quot;%s) Restore %s to--&gt;&gt;&gt; %s&quot; %( k,rh[k][0],rh[k][1])                         
                    restoreyesno = raw_input( &quot;Continue to restore [y|n]?: &quot;)
                    if restoreyesno in [&quot;n&quot;,&quot;N&quot;]: break
                    elif restoreyesno in [&quot;y&quot;,&quot;Y&quot;]: 
                        rchoice = raw_input(&quot;Enter choice to restore: &quot;)
                        for n, olines in enumerate(open( os.path.join(restorepath,ofilename))):
                            From,To = olines.strip().split(&quot;,&quot;)
                            n=n+1
                            if &quot;All&quot; in rh[int(rchoice)] or &quot;Original&quot; in rh[int(rchoice)] :  
                                try:
                                    os.rename(From,To)
                                except Exception,e:
                                    print &quot;Error restoring: &quot;,e
                            
                            elif n==int(rchoice):
                                try:
                                    os.rename(From,To)
                                except Exception,e:
                                    print &quot;Error restoring: &quot;,e
        
    # directory key    
    if options.has_key('-D') and options['-D'] != []:
        depthcnt ,newpath, ret = pathChecker(options['-D'])    #check the root, whether exists   
        if ret == -1:
            print &quot;%s does not exists. &quot; % (options['-D'] )
            sys.exit(2)
        options['-D'] = newpath
    else :        
        # if not -D specified, take current directory
        depthcnt ,newpath, ret = pathChecker(os.getcwd())        
        options['-D'] = os.getcwd()      

    DIR=options['-D']
    

            
    # check bad options...
    for bad_ops in bad_options :        
        if combocheck( bad_ops, keys) :
            usage(basename)
            sys.exit(0)      
    
    # Check for maxdepth
    if options.has_key('-d'): 
        maxdepth = int(options['-d']) + depthcnt
    else: 
        maxdepth = depthcnt
    
    # check for list flag - debug mode , 0 for commit.
    if not options.has_key('-l'): DEBUG = 0 
    
    # check for inverse pattern search,similar to grep's -v
    if options.has_key('-v'): INVERSE = 1
    
    # check numerical sorting
    if options.has_key('-n'): SORT = 1
    
    #check file type, whether search file or directory    
    if options.has_key('-t'): 
        TYPE=options['-t']

    if options.has_key('-i')  :
        patold=options['-i']
        patnew=&quot;front&quot;
        ACTION=&quot;insert&quot;
        
    #insert at back of file name
    if options.has_key('-b')  :
        patold=options['-b']
        patnew=&quot;back&quot;
        ACTION=&quot;insert&quot;
                    
    if options.has_key('-c') and options.has_key('-e') :                    
        patold=options['-c']        
        patnew=options['-e']
        ACTION=&quot;char&quot;
    elif options.has_key('-c') and not options.has_key('-e'):
        patold=options['-c']        
        patnew=&quot;&quot;
        ACTION=&quot;char&quot;        
                    
    if options.has_key('-s') and options.has_key('-e') : 
        patold=options['-s']
        patnew=options['-e']        
        if patnew == &quot;&quot; : usage(basename); sys.exit(1)
        ACTION=&quot;seq&quot;
    elif options.has_key('-s') and not options.has_key('-e'):usage(basename) ;sys.exit()
        
    
    if options.has_key('-p') and options.has_key('-e') : 
        patold=options['-p'];patnew=options['-e']
    elif options.has_key('-p') and not options.has_key('-e'): usage(basename) ;sys.exit()
    
    if options.has_key('-v'):
        INVERSE=1
    
    # ignore case sensitivity
    if options.has_key('-I'): CASE=0
        
    if options.has_key('-Z'):          
        patold=options['-Z']
        if not patold : usage(basename);sys.exit(1)
        patnew=&quot;&quot;
        ACTION=&quot;delete&quot;
        
    # do the walking.
    try:
        doWalk(DIR,maxdepth,TYPE,ACTION,patold,patnew,DEBUG,INVERSE,CASE,SORT,FileNames)
    except:
        usage(basename)
        sys.exit()</pre>
</div><div style="margin:20px; margin-top:5px; ">
	<div class="smallfont" style="margin-bottom:2px">Quote:</div>
	<table cellpadding="3" cellspacing="0" border="0" width="100%">
	<tr>
		<td class="bbcodeblock" style="border:1px inset">
			
				<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="bbcodeblock" dir="ltr" style="
		margin: 0px;
		margin-right: -99999px;
		padding: 3px;
		border: 1px inset;
		width: 98%;
		height: 498px;
		text-align: left;
		overflow: auto">Some examples:
1) Changing cases:
   a) Change case of 2nd to 3rd character of all files starting with &quot;test&quot; to upper case.
      ---&gt; filerenamer.py -c 1:3 -e &quot;[A-Z]&quot; -l &quot;test*&quot;
   b) Change case of 2nd till last 4th character of all files to lower case      
      ---&gt; filerenamer.py -c 2:-4 -e &quot;[a-z]&quot; -l &quot;*&quot;
   c) Change file name to all upper case
      ---&gt; filerenamer.py -c 0: -e &quot;[A-Z]&quot; -l &quot;*&quot;

2) Change file names by substitution:
   a) Change the word &quot;test&quot; to &quot;foo&quot; for all files starting with &quot;test&quot;
      ---&gt; filerenamer.py -p &quot;test&quot; -e &quot;foo&quot; -l &quot;test*&quot;

3) Change file names to a number sequence
   a) Change the word &quot;test&quot; in files starting with test to number sequence 001 to 100 
      ---&gt; filerenamer.py -s &quot;test&quot; -e &quot;001:100&quot; -l &quot;test*&quot;
   b) Change the word &quot;test&quot; in files starting with test to &quot;foo&quot; and number sequence 001 to 100
      ---&gt; filerenamer.py -s &quot;test&quot; -e &quot;foo001:100&quot; -l &quot;test*&quot;
           * changes testbar.txt to foo001bar.txt 
   c) Change the word &quot;test&quot; in files starting with test to number sequence 001 to 100 followed by &quot;foo&quot;
      ---&gt; filerenamer.py -s &quot;test&quot; -e &quot;01:20foo&quot; -l &quot;test*&quot;
           * changes testbar.txt to 001foobar.txt 

4) Removing characters by position
   a) Remove the first 5 characters for files starting with &quot;test&quot;
      ---&gt; filerenamer.py -c 0:5 -l &quot;test*&quot;
   b) Remove the last 5 characters for files starting with &quot;test&quot;
      ---&gt; filerenamer.py -c -5: -l &quot;test*&quot;
   c) Remove 2nd character from all files
      ---&gt; filerenamer.py -c 1 -l &quot;*&quot;

   NB: uses the python indexing convention.</pre>
</div>
			
		</td>
	</tr>
	</table>
</div></div>

]]></content:encoded>
			<dc:creator>ghostdog74</dc:creator>
			<guid isPermaLink="true">http://www.linuxquestions.org/questions/blog.php?b=1190</guid>
		</item>
		<item>
			<title>Simple Hangman Game</title>
			<link>http://www.linuxquestions.org/questions/blog.php?b=1187</link>
			<pubDate>Tue, 16 Sep 2008 11:35:25 GMT</pubDate>
			<description><![CDATA[I was so bored today, that i created this simple hangman game to entertain myself. Makes use of a dictionary file called "english" to get random word...]]></description>
			<content:encoded><![CDATA[<div>I was so bored today, that i created this simple hangman game to entertain myself. Makes use of a dictionary file called &quot;english&quot; to get random word to guess. No fancy stuff like drawing the man, only number of tries (set to 10)<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="bbcodeblock" dir="ltr" style="
		margin: 0px;
		margin-right: -99999px;
		padding: 3px;
		border: 1px inset;
		width: 98%;
		height: 498px;
		text-align: left;
		overflow: auto">#!/bin/bash

awk  'BEGIN{
    dictfile=&quot;english&quot;
    l=&quot;abcdefghijklmnopqrstuvwxyz&quot;
    while (1) {
        srand()
        lm=split(l,letters,&quot;&quot;)
        if ( ( getline &lt; dictfile) &lt;= 0 ) {
            print &quot;Dictionary file does not exists&quot;
        }else {
            tries=10
            count=getlinecount(dictfile)
            num=int(rand() * count) +  1
            WORD=randomword(dictfile,num)
            gsub(/[[:blank:]]$|[[:space:]]|[0-9]+$/,&quot;&quot;,WORD)
            WORD=tolower(WORD)
            m=split(WORD,word,&quot;&quot;)
            for(i=1;i&lt;=m;i++){ THEWORD[i] =&quot;_&quot; }
            for(j=1;j&lt;=m;j++){ printf &quot;%s&quot;,THEWORD[j] }
            print &quot;&quot;
            while(tries&gt;0){
                flag=0
                printf &quot;Choose a letter (Enter full word to complete): &quot;
                printf &quot;You have &quot;tries&quot; tries\n&quot;
                for(o=1;o&lt;=lm;o++){ printf letters[o] }
                print &quot;&quot;
                getline LETTER &lt; &quot;-&quot;
                if ( LETTER==WORD || join(THEWORD,1,m,SUBSEP) == WORD ) {
                    print &quot;congratulations! &quot;
                    exit
                }
                system(&quot;clear&quot;)
                for( o=1;o&lt;=m;o++) {
                    if ( word[o] == LETTER ) {
                        flag=1
                        THEWORD[o]=LETTER
                        for(i in letters){
                            if ( letters[i]==LETTER) { delete letters[i] }
                        }
                    }
                }
                if (flag==0){ tries-- }
                for(i=1;i&lt;=m;i++){
                    printf THEWORD[i]
                }
                print &quot;&quot;
            }

            print &quot;You hanged yourself!&quot;
            print &quot;The answer is &quot;WORD
        }
    }
}
function getlinecount(file){
    count=0
    while ( ( getline &lt; file ) &gt; 0 ) count++
    close(file)
    return count
}
function randomword(file,linenumber){
    count=0
    while ( ( getline dictline&lt; file) &gt; 0 ) {
        count++
        if (  count == linenumber) {
            gsub(/[[:punct:]]/,&quot;&quot;,dictline)
            gsub(/ +$/,&quot;&quot;,dictline)
            m=split(dictline,toguess,&quot; &quot;)
            if (m&gt;1){
                num = int(rand() * m) +  1
                return toguess[num]
            }else {
                return dictline
            }
        }
    }
    close(file)
}
function join(array, start, end, sep,    result, i)
{
        if (sep == &quot;&quot;)
                sep = &quot; &quot;
        else if (sep == SUBSEP) # magic value
                sep = &quot;&quot;
        result = array[start]
        for (i = start + 1; i &lt;= end; i++)
                result = result sep array[i]
        return result

}
'</pre>
</div></div>

]]></content:encoded>
			<dc:creator>ghostdog74</dc:creator>
			<guid isPermaLink="true">http://www.linuxquestions.org/questions/blog.php?b=1187</guid>
		</item>
		<item>
			<title>Mass File Renamer: Changing Cases(Upper/Lower)</title>
			<link>http://www.linuxquestions.org/questions/blog.php?b=1182</link>
			<pubDate>Sun, 14 Sep 2008 02:50:10 GMT</pubDate>
			<description><![CDATA[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"]]></description>
			<content:encoded><![CDATA[<div><div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="bbcodeblock" dir="ltr" style="
		margin: 0px;
		margin-right: -99999px;
		padding: 3px;
		border: 1px inset;
		width: 98%;
		height: 498px;
		text-align: left;
		overflow: auto">#!/bin/bash
## Change file names into uppper/lower case, or by position.
NO_ARGS=0 
E_OPTERROR=65
DEBUG=0
UPPER=0
FNAME=&quot;f&quot;
maxdepth=1
directory=`pwd`
set -o noglob
#---- Functions ------------#

usage() {
 printf &quot;Usage: `basename $0` [-D directory] [-M depth] [-U ] [-p pattern] [-c position ][-d] [-X] [filename(s)]\n&quot;
 cat &lt;&lt; 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 &quot;*.txt&quot;. If omitted, default to all files. Use quotes.
        Example: 
        1) -U -p file &quot;*.txt&quot; ===&gt; change all name of text files with pattern &quot;file&quot; to upper case.
        2) -U -c 10 &quot;*.txt&quot; ===&gt; change the 10th character to upper case
        3) -c 2 &quot;*FILE*&quot; ===&gt; change the 2nd character to lower case for all files with pattern &quot;FILE&quot; in file name.
EOF

}
#----------------------------#

if [ $# -eq &quot;$NO_ARGS&quot; ]  # Script invoked with no command-line args?
then
   usage
   exit $E_OPTERROR        # Exit and explain usage, if no argument(s) given.
fi  


while getopts &quot;:D:s:e:M:p:c:dUX&quot; 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 &quot;${pattern}&quot; ] &amp;&amp; pattern=&quot;.*&quot;
            ;;
    M     ) maxdepth=$OPTARG
            case ${maxdepth} in
                0 | *[a-z]*|&quot;&quot;) maxdepth=1;;   
            esac
            ;;
    X     ) FNAME=&quot;d&quot;;;
    *     ) echo &quot;Unimplemented option chosen.&quot;
            exit;;
  esac
done
shift $(($OPTIND - 1))

# get last argument

argument=$#
if [ $argument -eq 0 ];then
    ext=&quot;*&quot;
else    
    ext=$(eval echo \&quot;\${${argument}}\&quot;)
fi


find &quot;${directory}&quot; -maxdepth &quot;${maxdepth}&quot; -type &quot;${FNAME}&quot; -name &quot;$ext&quot; -printf &quot;%f:%h:%p\n&quot; | \
awk -F&quot;:&quot; -v pattern=&quot;${pattern}&quot; -v debug=&quot;$DEBUG&quot; -v upper=${UPPER} -v position=&quot;${position}&quot; 'BEGIN{
    q=&quot;\042&quot;
}
$1 ~ pattern{  
    if ( upper ) {
        
        if ( position&gt;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)&lt;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 == &quot;.*&quot; ) {
                newname = toupper($1)
            }else {
                newname=$1
                gsub(pattern,toupper(pattern),newname)            
            }
        }
    }else if (!upper) { 
        if ( position&gt;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)&lt;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 == &quot;.*&quot; ) {
                newname = tolower($1)
            }else {
                newname=$1
                gsub(pattern,tolower(pattern),newname)            
            }                
        }
    }
    if ( newname == $1 ) {next}    
    if ( debug) {
        print &quot;mv -u &quot; q $3 q &quot; &quot;q $2 &quot;/&quot; newname q        
    }else {
        cmd = &quot;mv -u &quot; q $3 q &quot; &quot;q $2 &quot;/&quot; newname q        
        system(cmd)
    }
    
}'</pre>
</div>Usage:<br />
<br />
The script makes use of GNU find/awk. Maximum depth value passed to &quot;find&quot; is set to default 1 level. Issue -M &lt;level&gt; 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 &lt;directory&gt; is omitted, the script searches from current working directory onwards.<br />
Use -U ( or omit for lower case) for changing to upper case.<br />
<br />
# Execute the script name without any arguments to show help.<br />
&gt; ./script.sh<br />
<br />
# To see results before making actual changes, use the -d switch.<br />
&gt; ./script.sh -D /path/1 -U  -p image <font color="red">-d</font> &quot;*.txt&quot;<br />
<br />
# To search text files in directories for 2 levels and change word &quot;file&quot; in their file names to Upper case <br />
&gt; ./script.sh -D /path/1 -M 2 -U -p &quot;file&quot; -d &quot;*.txt&quot;<br />
<br />
# To search text files in current directory and change word &quot;FILE&quot; in their file names to lower case <br />
&gt; ./script.sh -p &quot;FILE&quot; &quot;*.txt&quot;<br />
<br />
# To search text files in current directory and change the first character of each text file name to upper case <br />
&gt; ./script.sh -U -c 1 &quot;*.txt&quot;<br />
<br />
# To search text files in current directory and change the last 2nd character onwards of each text file name to lower case <br />
&gt; ./script.sh  -c -2 &quot;*.txt&quot;<br />
<br />
# To rename all file names to capital letters<br />
&gt; ./script.sh -U -p &quot;.*&quot; &quot;*.txt&quot;<br />
<br />
# To rename all file names to lower case letters<br />
&gt; ./script.sh -p &quot;.*&quot;  &quot;*.txt&quot;</div>

]]></content:encoded>
			<dc:creator>ghostdog74</dc:creator>
			<guid isPermaLink="true">http://www.linuxquestions.org/questions/blog.php?b=1182</guid>
		</item>
		<item>
			<title>Mass File Renamer: By Pattern Substitution</title>
			<link>http://www.linuxquestions.org/questions/blog.php?b=1181</link>
			<pubDate>Sun, 14 Sep 2008 02:37:00 GMT</pubDate>
			<description><![CDATA[Code: 
--------- 
#!/bin/bash 
## Change file names with a pattern substitution. 
NO_ARGS=0  
E_OPTERROR=65 
DEBUG=0 
FNAME="f" 
maxdepth=1]]></description>
			<content:encoded><![CDATA[<div><div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="bbcodeblock" dir="ltr" style="
		margin: 0px;
		margin-right: -99999px;
		padding: 3px;
		border: 1px inset;
		width: 98%;
		height: 498px;
		text-align: left;
		overflow: auto">#!/bin/bash
## Change file names with a pattern substitution.
NO_ARGS=0 
E_OPTERROR=65
DEBUG=0
FNAME=&quot;f&quot;
maxdepth=1
directory=`pwd`
set -o noglob

#---- Functions ------------#

usage() {
 printf &quot;Usage: `basename $0` [-D directory] [-M depth] [-s pattern_from ] [-e pattern_to ] [-d] [-X] [filename(s)]\n&quot;
 cat &lt;&lt; '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], &quot;pattern1|pattern2&quot;.
             To input special characters, eg &quot;[\`&amp;*]&quot;,'[`&amp;*]'
        -e : pattern to change to. To rename to null, use &quot;&quot;. eg -e &quot;&quot;
        -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 ===&gt; change all name of text files 
                 with pattern &quot;file&quot; to &quot;test&quot;. eg file_copy.txt will be changed to test_copy.txt
        
EOF

}
#----------------------------#

if [ $# -eq &quot;$NO_ARGS&quot; ]  # Script invoked with no command-line args?
then
   usage
   exit $E_OPTERROR        # Exit and explain usage, if no argument(s) given.
fi  


while getopts &quot;D:s:e:M:Xd&quot; Option
do
  case $Option in
    D     ) directory=$OPTARG
            ;;
    s     ) startseq=$OPTARG            
            [ -z &quot;${startseq}&quot; ] &amp;&amp; echo &quot;Pattern not specified. Use -s &lt;pattern_from&gt; and -e &lt;pattern_to&gt;&quot; &amp;&amp; exit    
            ;;
    e     ) endseq=$OPTARG
            [ -z &quot;${endseq}&quot; ] &amp;&amp; endseq=&quot;&quot;
            ;;    
    d     ) DEBUG=1 ;;
    X     ) FNAME=&quot;d&quot;;;
    M     ) maxdepth=$OPTARG
            case ${maxdepth} in
                0 | *[a-z]* |&quot;&quot;) maxdepth=1;;   
            esac
            ;;
    *     ) echo &quot;Unimplemented option chosen.&quot;
            exit;;
  esac
done
shift $(($OPTIND - 1))


# get last argument

argument=$#
if [ $argument -eq 0 ];then
    ext=&quot;*&quot;
else    
    ext=$(eval echo \&quot;\${${argument}}\&quot;)
fi



find &quot;${directory}&quot; -maxdepth ${maxdepth} -type &quot;${FNAME}&quot; -name &quot;$ext&quot; -printf &quot;%f:%h:%p\n&quot; | \
awk -F&quot;:&quot; -v startseq=&quot;${startseq}&quot; -v endseq=&quot;${endseq}&quot; -v debug=&quot;$DEBUG&quot; 'BEGIN{}
$1 ~ startseq{       
    original=$1
    sq=&quot;\047&quot;
    q=&quot;\042&quot;
    flag=0
    s = gsub (startseq, endseq,$1 )
    if ( startseg ~ /'&quot;\'&quot;'/) { sq=&quot;\042&quot; }    
    if ( startseq ~ /[[:punct:]]/ ) { flag=1} #if found special characters/punctuation
    if ( debug) {
        if(flag) { print &quot;mv -u &quot; q $2&quot;/&quot; q sq original sq &quot; &quot;q $2 &quot;/&quot; $1 q  }
        else{   print &quot;mv -u &quot; q $3 q &quot; &quot;q $2 &quot;/&quot; $1 q        }
    }
    else {
         if(flag) { cmd= &quot;mv -u &quot; q $2&quot;/&quot; q sq original sq &quot; &quot;q $2 &quot;/&quot; $1 q }
         else{  cmd = &quot;mv -u &quot; q $3 q &quot; &quot;q $2 &quot;/&quot; $1 q }
         system(cmd)
    }
    
}'</pre>
</div>Usage:<br />
<br />
Usage:<br />
<br />
The script makes use of GNU find/awk. Maximum depth value passed to &quot;find&quot; is set to default 1 level. Issue -M &lt;level&gt; 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 &lt;directory&gt; is omitted, the script searches from current working directory onwards.<br />
<br />
# Execute the script name without any arguments to show help.<br />
&gt; ./script.sh<br />
<br />
# To see results before making actual changes, use the -d switch.<br />
&gt; ./script.sh -D /path/1 -M 2 -s &quot;from&quot; -e &quot;to&quot; [color=red]-d[/code] &quot;*.txt&quot;<br />
<br />
# To rename files with extension &quot;.txt&quot; and word &quot;image&quot; in their file names to &quot;file&quot; and search directories for 2 levels.<br />
&gt; ./script.sh -D /path/1 -M 2 -s &quot;image&quot; -e &quot;file&quot; &quot;*.txt&quot;<br />
<br />
# To rename all files in the current directory with word &quot;file&quot; or &quot;image&quot; to &quot;test&quot; without traversing directories<br />
&gt; ./script.sh -s &quot;file|image&quot; -e &quot;test&quot; -d<br />
<br />
# To rename all files in current directory with more than 1 numbers to &quot;test&quot;.<br />
&gt; ./script.sh -s &quot;[0-9]+&quot; -e &quot;test&quot; -d<br />
<br />
# To replace special characters eg ' (single quote), &amp; ,!<br />
&gt; ./script.sh -s &quot;[!]&quot; -e &quot;&quot; -d</div>

]]></content:encoded>
			<dc:creator>ghostdog74</dc:creator>
			<guid isPermaLink="true">http://www.linuxquestions.org/questions/blog.php?b=1181</guid>
		</item>
		<item>
			<title>Mass File Renamer: By Number Sequence</title>
			<link>http://www.linuxquestions.org/questions/blog.php?b=1180</link>
			<pubDate>Sun, 14 Sep 2008 02:19:22 GMT</pubDate>
			<description><![CDATA[Code: 
--------- 
#!/bin/bash 
## Change file names into a sequence of numbers. 
NO_ARGS=0  
E_OPTERROR=65 
DEBUG=0 
FNAME="f" 
maxdepth=1]]></description>
			<content:encoded><![CDATA[<div><div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<pre class="bbcodeblock" dir="ltr" style="
		margin: 0px;
		margin-right: -99999px;
		padding: 3px;
		border: 1px inset;
		width: 98%;
		height: 498px;
		text-align: left;
		overflow: auto">#!/bin/bash
## Change file names into a sequence of numbers.
NO_ARGS=0 
E_OPTERROR=65
DEBUG=0
FNAME=&quot;f&quot;
maxdepth=1
directory=`pwd`
set -o noglob

#---- Functions ------------#

usage() {
 printf &quot;Usage: `basename $0` [-D directory] [-M depth]  [-s startseq] [-e endseq] [-p pattern] [-d] [-X] [filename(s)]\n&quot;
 cat &lt;&lt; EOF
        -D : starting directory. Default=current directory.
        -M : max depth to recurse subdirectories (default=1), eg 1,2
        -s : starting sequence, eg 1,01,001,0001
        -e : ending sequence, eg 7, 12,1001. No effect with leading zeroes. Can be used with a tag
             Eg -s 001 -e image20 -p &quot;file&quot; ==&gt;  files will be named image001 to image020, replacing the word &quot;file&quot; in the filename
        -p : pattern to be substituted with the sequence. Can be simple shell patterns. eg [0-9], [a-z]
             Use &quot;.*&quot; to specify ALL files to be changed.
        -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: 
            1) -s 1 -e 12 -p &quot;file&quot; -d *.txt ===&gt; change all name of text files 
                 with pattern &quot;file&quot; with sequence starting from 1 till 12
            2) -s 001 -e 12 -p &quot;.*&quot;  ==&gt; change ALL files to sequence 001 to 012
            3) -s 00001 -e &quot;file.30&quot; -p &quot;file&quot; &quot;*.txt&quot; =====&gt; change all text files with word &quot;file&quot; to file.00001 to file.00030
            4) -s 01 -e &quot;40.images&quot; -p &quot;file&quot; &quot;*.jpg&quot; ====&gt; change all jpg files with word &quot;file&quot; to &quot;01.images&quot; till &quot;40.images&quot;
        
EOF

}
#----------------------------#

if [ $# -eq &quot;$NO_ARGS&quot; ]  # Script invoked with no command-line args?
then
   usage
   exit $E_OPTERROR        # Exit and explain usage, if no argument(s) given.
fi  


while getopts &quot;:D:s:e:p:M:Xd&quot; Option
do
  case $Option in
    D     ) directory=$OPTARG
            ;;
    s     ) startseq=$OPTARG;;
    e     ) endseq=$OPTARG;;
    p     ) 
            pattern=$OPTARG
            [ -z &quot;${pattern}&quot; ] &amp;&amp; pattern=&quot;.*&quot;    
            ;;
    M     ) 
            maxdepth=$OPTARG            
            case ${maxdepth} in
                0 | *[a-z]*| &quot;&quot;) maxdepth=1;; 
            esac    
            ;;
    d     ) DEBUG=1 ;;
    X     ) FNAME=&quot;d&quot;;;
    *     ) echo &quot;Unimplemented option chosen.&quot;
            exit;;
  esac
done
shift $(($OPTIND - 1))

# get last argument

argument=$#
if [ $argument -eq 0 ];then
    ext=&quot;*&quot;
else    
    ext=$(eval echo \&quot;\${${argument}}\&quot;)
fi

find &quot;${directory}&quot; -maxdepth &quot;${maxdepth}&quot; -type &quot;${FNAME}&quot; -name &quot;$ext&quot; -printf &quot;%f:%h:%p\n&quot; | \
awk -F&quot;:&quot; -v startseq=&quot;$startseq&quot; -v endseq=&quot;$endseq&quot; -v pattern=&quot;$pattern&quot; -v debug=&quot;$DEBUG&quot; 'BEGIN{
    q=&quot;\042&quot;    
    match(endseq,&quot;[0-9]&quot;) # get starting index of number 
    index_num=RSTART
    match(endseq,&quot;[^0-9]&quot;) #get starting index of not number
    index_alpha=RSTART
    numendseq=endseq
    strendseq = endseq
    gsub(/[^0-9]+/,&quot;&quot;,numendseq) #get number
    gsub(/[0-9]+/,&quot;&quot;,strendseq) #get besides number
    endseq=numendseq
    lenseq = length(endseq)
    lenstseq = length(startseq)    
    # generate sequence
    for ( i = startseq+0 ; i&lt;=endseq+0 ; i++ ){
        _=&quot;0&quot;lenstseq 
        num[++d]=sprintf(&quot;%0*d&quot; , _ ,i)
    }
}

$1 ~ pattern{    
    ++e 
    if ( index_alpha &gt; index_num ) {        
        s = gsub (pattern, num[e] strendseq , $1 )    
    }else {
        s = gsub (pattern, strendseq num[e] , $1 )
    }
    if ( debug) {
        print &quot;mv -u &quot; q $3 q &quot; &quot;q $2 &quot;/&quot; $1 q        
    }else {
        cmd = &quot;mv -u &quot; q $3 q &quot; &quot;q $2 &quot;/&quot; $1 q
        system(cmd)
    }
    if ( d==e ) { exit }
    
}'</pre>
</div><br />
Usage:<br />
<br />
The script makes use of GNU find/awk. Maximum depth value passed to &quot;find&quot; is set to default 1 level. Issue -M &lt;level&gt; 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 &lt;directory&gt; is omitted, the script searches from current working directory onwards.<br />
<br />
# Execute the script name without any arguments to show help.<br />
&gt; ./script.sh<br />
<br />
# To see results before making actual changes, use the -d switch.<br />
&gt; ./script.sh -D /path/1 -M 2 -s 001 -e 100 -p image <font color="red">-d</font> &quot;*.txt&quot;<br />
<br />
# To rename files with extension &quot;.txt&quot; and word &quot;image&quot; in their file names with starting sequence 001 till ending sequence 100 and search directories for 2 levels.<br />
&gt; ./script.sh -D /path/1 -M 2 -s 001 -e 100 -p image &quot;*.txt&quot;<br />
<br />
If the number of files found is less than 100, the script will stop.<br />
<br />
# To rename all files in the current directory from 01 to 12 without traversing directories<br />
&gt; ./script.sh -s 01 -e 12 -p &quot;.*&quot; <br />
<br />
# To rename all jpg files in the current directory with word &quot;file&quot; from 01 to 100 without traversing directories, and at the same time, tagging the word &quot;image&quot; in front of the ending sequence<br />
&gt; ./script.sh -s 01 -e image100 -p &quot;file&quot; -d  &quot;*.jpg&quot;<br />
<br />
# To rename all jpg files in the current directory with word &quot;file&quot; from 01 to 100 without traversing directories, and at the same time, tagging the word &quot;image&quot; behind the ending sequence<br />
&gt; ./script.sh -s 01 -e 100image -p &quot;file&quot; -d  &quot;*.jpg&quot;<br />
</div>

]]></content:encoded>
			<dc:creator>ghostdog74</dc:creator>
			<guid isPermaLink="true">http://www.linuxquestions.org/questions/blog.php?b=1180</guid>
		</item>
	</channel>
</rss>
