Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Perl rename not working

Options
  • 22-06-2005 12:33am
    #1
    Closed Accounts Posts: 285 ✭✭


    I am writing a perl (5.6.0) script to rename files downloaded from my digital camera as they are all IMG_xxxx.tif etc and I need something more unique.

    Machine is running XP pro.

    The directory structure I have is like this
    Picture
    |
    |_D-00001
    |  |
    |  |_tifs
    |  |  |
    |  |  |_IMG_0003.tif
    |  |  |_IMG_0012.tif
    |  |_DNGs
    |     |
    |     |_IMG_0005.dng
    |     |_IMG_0212.dng
    |
    |_D-00002
       |
       |_tifs
       |  |
       |  |_IMG_0041.tif
       |  |_IMG_0032.tif
       |_DNGs
          |
          |_IMG_0005.dng
          |_IMG_0212.dng
       
    

    so I want to go in and rename IMG_0001.tif to D-00001_0001.tif etc

    I pulled the following from O'Reilly and modded it to do the above. It runs but it only does the first file in each dir (tif and dng) but refuses to rename the others. Even if I rerun it it will not do it. It looks like windows doesn't like the name for the second file. I'm wondering if there are any hidden chars in the name that clash with the first file or something... any ideas appreciated...

    use Cwd; # module for finding the current working directory
    
    sub ScanDirectory
    {
        my ($workdir) = shift; 
    
        my ($startdir) = &cwd; # keep track of where we began
    
        chdir($workdir) or die "Unable to enter dir $workdir:$!\n";
        opendir(DIR, ".") or die "Unable to open $workdir:$!\n";
        my @names = readdir(DIR) or die "Unable to read $workdir:$!\n";
        closedir(DIR);
    
        foreach my $name (@names)
        {
            next if ($name eq "."); 
            next if ($name eq "..");
    
            if (-d $name)
    	{                  			# is this a directory?
                	&ScanDirectory($name);
                	next;
            }
            if ($name =~ /^IMG/) 
    	{          				# is this a file named "IMGxxx.xxx"?
                
    	    	@fullpath=split(/(?:\/)/,$startdir);	#find out where you are
    	    	$newleader = $fullpath[$#fullpath];	#get the directory name
    	    
    	    	if ($newleader =~ /^D-/ )
    		{
    	    
    	   		@twopart=split(/(?:\IMG)/,$name);	
    	    		$trailer = $twopart[1];
    	 		$newname=$newleader . $trailer;
    	    		print "Renaming... [$name] -> [$newname] \n";
    			
    			if (rename ($name , $newname))
    			{ 
    		        	print "Renamed $newleader\\$workdir\\$name -> $newname \n"; 
    			}
    			else
    			{ 
    				
    				print "Error: Rename $name -> $newname failed in $newleader\\$workdir! \n"; 
    				
    				
    			}
    		} 
    	    	      
    	
    		else
    		{ 
    			die "Bad directory name $newleader \n";
    		}
    	}
            
        	chdir($startdir) or 
    		die "Unable to change to dir $startdir:$!\n";
        }
    }
    
    
    
    &ScanDirectory(".");     
    




    this is the output I get....


    First run....
    C:\Pictures>ren.pl
    Renaming... [IMG_0003.dng] -> [D-00001_0003.dng]
    Renamed D-00001\DNGs\IMG_0003.dng -> D-00001_0003.dng
    Renaming... [IMG_0012.dng] -> [D-00001_0012.dng]
    Error: Rename IMG_0012.dng -> D-00001_0012.dng failed in D-00001\DNGs!
    Renaming... [IMG_9912.dng] -> [D-00001_9912.dng]
    Error: Rename IMG_9912.dng -> D-00001_9912.dng failed in D-00001\DNGs!
    Renaming... [IMG_0012.tif] -> [D-00001_0012.tif]
    Renamed D-00001\Tiffs\IMG_0012.tif -> D-00001_0012.tif
    Renaming... [IMG_0023.tif] -> [D-00001_0023.tif]
    Error: Rename IMG_0023.tif -> D-00001_0023.tif failed in D-00001\Tiffs!
    Renaming... [IMG_9912.tif] -> [D-00001_9912.tif]
    Error: Rename IMG_9912.tif -> D-00001_9912.tif failed in D-00001\Tiffs!


    second run....
    C:\Pictures>ren.pl
    Renaming... [IMG_0012.dng] -> [D-00001_0012.dng]
    Error: Rename IMG_0012.dng -> D-00001_0012.dng failed in D-00001\DNGs!
    Renaming... [IMG_9912.dng] -> [D-00001_9912.dng]
    Error: Rename IMG_9912.dng -> D-00001_9912.dng failed in D-00001\DNGs!
    Renaming... [IMG_0023.tif] -> [D-00001_0023.tif]
    Error: Rename IMG_0023.tif -> D-00001_0023.tif failed in D-00001\Tiffs!
    Renaming... [IMG_9912.tif] -> [D-00001_9912.tif]
    Error: Rename IMG_9912.tif -> D-00001_9912.tif failed in D-00001\Tiffs!


    third etc run...
    C:\Pictures>ren.pl
    Renaming... [IMG_0012.dng] -> [D-00001_0012.dng]
    Error: Rename IMG_0012.dng -> D-00001_0012.dng failed in D-00001\DNGs!
    Renaming... [IMG_9912.dng] -> [D-00001_9912.dng]
    Error: Rename IMG_9912.dng -> D-00001_9912.dng failed in D-00001\DNGs!
    Renaming... [IMG_0023.tif] -> [D-00001_0023.tif]
    Error: Rename IMG_0023.tif -> D-00001_0023.tif failed in D-00001\Tiffs!
    Renaming... [IMG_9912.tif] -> [D-00001_9912.tif]
    Error: Rename IMG_9912.tif -> D-00001_9912.tif failed in D-00001\Tiffs!


Comments

  • Registered Users Posts: 1,268 ✭✭✭hostyle


    Sounds like your paths are getting lost / confused along the way. Can you print out the full paths along the way to check (instead of just the filenames).


  • Registered Users Posts: 6,508 ✭✭✭daymobrew


    I find the File::Find module great for recursive stuff like this.
    You can get it to descend into the directories, removing the need to deal with the full path, or tell it not to chdir, which is especially useful if you want to store the full path.

    After lunch I'll see if I can scribble together a port of your code to use File::Find.


  • Registered Users Posts: 6,508 ✭✭✭daymobrew


    #!/usr/bin/perl -w
    
    use strict;
    use File::Find;
    
    sub wanted
    {
        if ( ( -f $File::Find::name ) && ( $File::Find::name =~ /IMG/ ) )
        {
         	my $newname = $File::Find::name;
    	if ( $newname =~ /(D-\d+)/ )
    	{
                my $ddir = $1;
                $newname =~ s/IMG/$ddir/;
                rename( $File::Find::name, $newname );
                print "rename( $File::Find::name, $newname )\n";
    	}
        }
    }
    
    sub ScanDirectory( $ )
    {
        my ($workdir) = shift;
        find( { wanted => \&wanted, no_chdir => 1 }, $workdir );
    }
    
    ScanDirectory( '.' );
    

    This did the job with my little experiment. Error checking left as exercise blah blah.


  • Closed Accounts Posts: 285 ✭✭marauder


    That did the trick !
    thanks a lot :D


Advertisement