Mass/Batch renaming of files based on list

Discussion in 'Programming' started by LittlBUGer, Oct 25, 2007.

  1. #1
    Hello all you programmers/coders out there. I have a question if anyone can answer. To put things briefly....

    I'm moving servers/hosts soon and putting in some load balancing for my downloads site by moving the downloads to a couple mirrored download servers. This is fine except for how my downloads script works. Currently, when you add files, it copies them to the main download folder and then renames them to a certain "masked" name. It then stores the masked name and the real name of the files in the database, so that when a user downloads a file, it renames it to the real name on the fly. So the local file may have a masked name of "28o24309usf0h2kj223.rwd" or "thisisafile1.rwd" and the actual real file name is "thisisafile1.exe".

    Because of the new servers and load-balancing stuff, I need to be able to have an automated method of parsing through a list which has the masked file name and the real file name respectively and have it search through the actual files in the folder and rename them to their real file name on the fly. I've done some web programming and SQL stuff, but I haven't really messed with manipulating a lot of files on the fly like that before. Does anyone know of a program that could do this for me? If not, is anyone willing to create some sort of batch file or vb script or something that would do this for me? I have about 260 files to rename and I'd be willing to pay you for your time.

    I can give more details if needed as long as you just contact me. Thanks. :)
     
    LittlBUGer, Oct 25, 2007 IP
  2. gota

    gota Peon

    Messages:
    20
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #2
    Seems simply enough....

    At the top of the script there are (3) constants....

    (1)

    const DIRECTORY_PATH = "C:/files/"
    Code (markup):
    The value represent the full path to the base directory where any files found in that directory or any sub-directory below it will be renamed if a match is found. The value must be the full path (drive_letter:/path/). must end with forward slash!

    (2)

    const RENAME_FILE    = "C:/rename.txt"
    Code (markup):
    The value represents the full path & name of the rename file that contains a list of files to be renamed. The rename file is a simple text file that is in the following format!

    // rename.txt example

    abc.txt|def.jpg
    ghi.txt|jkl.jpg
    Code (markup):
    The left side of | contains the file name to search for. The right side of | contains the name that the file will be renamed to. So using the example above abc.txt would be renamed to def.jpg and ghi.txt would be renamed to jkl.txt

    (3)

    const RENAME_ONE     = true
    Code (markup):
    The value represents an internal switch that will stop the rename process after finding the first match. This allows the script to continue on to the next file search after the first rename is done. This should always have the value true, unless a single file to be renamed could have copies in lower directories. In that case the value would be false, so the script transverses through all directories rename all copies to!


    The script....

    rename.vbs

    	const DIRECTORY_PATH = "C:/files/"
    	const RENAME_FILE    = "C:/rename.txt"
    	const RENAME_ONE     = true
    
    	sub rename_item ( my_path, my_find, my_replace, my_stop )
    
    		dim done, hold, array_hold, file, directory, i, tmp, pos, rtl, stl, tsl
    
    		done = 1
    
    		hold = ""
    
    		do
    
    			dim dir, all
    
    			set dir = createobject ( "scripting.filesystemobject" )
    			set all = dir.getfolder ( my_path )
    
    			for each directory in all.subfolders
    
    				if (right(directory.name, 3) <> "cnf") then
    
    					if (hold = "") then
    
    						hold = hold & my_path & directory.name & "/"
    
    					else
    
    						hold = hold & "," & my_path & directory.name & "/"
    
    					end if
    
    				end if
    
    			next
    
    			for each file in all.files
    
    				if ( instr ( file.name, my_find ) > 0 ) then
    
    					file.name = my_replace
    
    					if ( my_stop ) then
    
    						hold = ""
    
    						exit for
    					end if
    
    				end if
    
    			next
    
    			if (hold = "") then
    
    				done = 0
    			else
    
    				array_hold = split(hold, ",")
    
    				hold = ""
    				
    				my_path = ""
    
    				for i = 0 to ubound(array_hold)
    
    					if (i < 1) then
    
    						my_path = my_path & array_hold(i)
    					else
    
    						if (i > 1) then
    
    							hold = hold & "," & array_hold(i)
    
    						else
    
    							hold = hold & array_hold(i)
    
    						end if
    
    					end if
    
    				next
    
    			end if
    
    			set dir = nothing
    			set all = nothing
    
    		loop while (done > 0)
    
    	end sub
    
    	dim da, io, so, line
    
    	set so = createobject ( "scripting.filesystemobject" )
    	set io = so.opentextfile ( RENAME_FILE, 1 )
    
    	da = split ( io.readall, vbnewline )
    
    	for each line in da
    
    		if (line <> "") then
    
    			dim item
    
    			item = split ( line, "|" )
    
    			call rename_item ( DIRECTORY_PATH, item(0), item(1), RENAME_ONE )
    
    		end if
    	
    	next
    
    	io.close
    	set so = nothing
    
    	wscript.quit(0)
    Code (markup):
    Also attached an example in a zip file in case the forum ruins the code in some way.
     

    Attached Files:

    gota, Oct 25, 2007 IP
  3. LittlBUGer

    LittlBUGer Peon

    Messages:
    306
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #3
    Ahh brilliant! Thank you very much. I will give that a try later on and let you know. :D
     
    LittlBUGer, Oct 25, 2007 IP
  4. LittlBUGer

    LittlBUGer Peon

    Messages:
    306
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #4
    I just tested it on a few files and it seems to work just fine. Thanks again! :)
     
    LittlBUGer, Oct 25, 2007 IP
  5. LittlBUGer

    LittlBUGer Peon

    Messages:
    306
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #5
    Again, I greatly appreciate your help, but there's something I completely spaced out yesterday about my needs for this script. It needs to run on a linux server (probably CentOS or something) and, though I'm not a linux expert, I don't think vbscript runs natively on linux. Is there a different way to go about this or do I just have no idea what I'm talking about? Thanks. :)
     
    LittlBUGer, Oct 26, 2007 IP
  6. gota

    gota Peon

    Messages:
    20
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #6
    You did say vb script, so I assumed you were working on windows. So my example was for that. I'll give you a PHP example, but next time always try to include the target system, it helps others trying to help you. If you want it in Perl , Python or any other language just tell me. I tend to use PHP as my first choice as people seem to like to use that.


    <?php
    
    define ( 'DIRECTORY_PATH', '/var/home/my_site/http_docs/files/' );
    define ( 'RENAME_FILE', '/var/home/my_site/http_docs/rename.txt' );
    define ( 'RENAME_ONE', true );
    
    function rename_item ( $old_name, $new_name )
    {
    	if ( is_dir ( DIRECTORY_PATH ) )
    	{
    		$dir = array ( DIRECTORY_PATH );
    
    		do
    		{
    			$current = array_shift ( $dir );
    
    			$files = glob ( $current . '*' );
    
    			if ( ! empty ( $files ) )
    			{
    				foreach ( $files AS $name )
    				{
    					if ( is_dir ( $name ) )
    					{
    						array_unshift ( $dir, $name . '/' );
    					}
    					else if ( false !== stripos ( basename ( $name ), $old_name ) )
    					{
    						rename ( $name, $current . $new_name );
    
    						if ( RENAME_ONE )
    						{
    							continue 2;
    						}
    						else
    						{
    							continue;
    						}
    					}
    				}
    			}
    
    		} while ( ! empty ( $dir ) );
    	}
    }
    
    $io = fopen ( RENAME_FILE, 'rb' );
    
    while ( ! feof ( $io ) )
    {
    	$line = trim ( fgets ( $io, 4096 ) );
    
    	if ( ! empty ( $line ) )
    	{
    		$item = explode ( '|', $line );
    
    		rename_item ( $item[0], $item[1] );
    	}
    }
    
    fclose ( $io );
    
    ?>
    PHP:
     
    gota, Oct 26, 2007 IP
  7. LittlBUGer

    LittlBUGer Peon

    Messages:
    306
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #7
    I know, and I do apologize for that. I didn't mean to waste your or anyone else's time. I was just anxious to get the post done and submitted and just wasn't even thinking about where I was actually going to have to run the script. I appreciate your time, again.

    Now, for the PHP, all I do is just something like "/usr/bin/php yourfile.php" in the linux shell? Thanks.
     
    LittlBUGer, Oct 26, 2007 IP
  8. gota

    gota Peon

    Messages:
    20
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #8
    It doesn't effect code really any, but you should change this...

    
                            if ( RENAME_ONE )
                            {
                                continue 2;
                            }
    PHP:


    Change to...

                            if ( RENAME_ONE )
                            {
                                continue 2;
                            }
                            else
                            {
                                continue;
                            }
    PHP:
    This way it exits out of the current directory, see there is never two of the same files in a directory...

    sorry, typing so fast I didn't think about that! I also updated my first post to fix the original PHP code!
     
    gota, Oct 26, 2007 IP