0

I'm working on a script in python to copy and rename a bunch of images based on a csv.

The image folder named "originals" is like:

Alpha_1.jpg

Beta_2.jpg

And the csv. contains:

Alfa_1.jpg 4474094_1

Beta_2.jpg 4474094_2

Beta_2.jpg 4474094_3

So the result should leave on a new folder named "newnames" the sames images like:

4474094_1.jpg

4474094_2.jpg

4474094_3.jpg

Where the 4474094_2.jpg and 4474094_3.jpg is the same picture as Beta_2.jpg

I have the following code which is not working, please any advice I would be most grateful!

  import os
  import csv
  import sys
  import shutil

  def copy_rename():
        os.chdir(r"C:\Transformer-SSBI\Original")
        saved_path = os.getcwd()
        file_list = os.listdir(saved_path)
        src_dir= r"C:\Transformer-SSBI\Originals"
        dst_dir= r"C:\Transformer-SSBI\Newnames"

        IDs = {}
        with open (r'transformer.csv','rb') as csvfile:    
                Reader = csv.reader(csvfile, delimiter = ';')
                for row in Reader:
                        IDs[row[0]] = row[1]+'.jpg'


                for row in IDs:
                        for file_name in file_list:    
                                if file_name in row:                                        
                                        oldname = shutil.copy(file_name,dst_dir)
                                        newname = IDs[file_name]
                                        os.rename(oldname, newname)


copy_rename()
NachoR
  • 31
  • 4

2 Answers2

0

since you store the mapping in a map, and Beta_2.jpg is renamed to two files,there can be only one key in the map,so it will only be renamed to 4474094_3.jpg,not 4474094_2.jpg,you can avoid the construction of map, and just do the renaming while iterating the csv files:

import os
import csv
import sys
import shutil

def copy_rename():
    src_dir= r"C:\Transformer-SSBI\Originals"
    dst_dir= r"C:\Transformer-SSBI\Newnames"
    or.chdir(dst_dir)
    with open (r'transformer.csv','rb') as csvfile:    
        Reader = csv.reader(csvfile, delimiter = ',')
        for row in Reader:
            oldname=row[0]
            newname=row[1]+".jpg"
            if os.path.exists(src_dir+"\\"+oldname):
                shutil.copy(src_dir+"\\"+oldname,dst_dir)             
                os.rename(oldname, newname)
copy_rename()
Samuelliyi
  • 68
  • 1
  • 7
  • 1
    The call to `os.path.exists` creates a race condition. This is safer if it is simply done within a `try/except` statement. – eestrada Nov 26 '15 at 02:57
  • thanks for the useful tip, i find similar question [here](http://stackoverflow.com/questions/1586648/race-condition-creating-folder-in-python) – Samuelliyi Nov 26 '15 at 04:56
0

This is like @Samuelliyi answer, except it avoids any race conditions and is (slightly) more cross platform by using os.path.join.

import os
import csv
import sys
import errno
import shutil

def copy_rename(src_dir, dst_dir, csv_path=None):
    if csv_path is None:
        csv_path = os.path.join(dst_dir, 'transformer.csv')

    with open (csv_path, mode='rb') as csvfile:    
        Reader = csv.reader(csvfile, delimiter = ',')
        for row in Reader:
            oldname = row[0]
            newname = row[1] + os.path.splitext(oldname)[1]
            oldpath = os.path.join(src_dir, oldname)
            newpath = os.path.join(dst_dir, newname)
            try:
                # the rename is implicit in the copy operation
                shutil.copy(oldpath, newpath)
            except OSError as e:
                # only raise exception if it is something other than the file
                # not existing
                if e.errno != errno.ENOENT:
                    raise

src_dir= r"C:\Transformer-SSBI\Originals"
dst_dir= r"C:\Transformer-SSBI\Newnames"
copy_rename(src_dir, dst_dir)

Also, the function is now more general and can be used on any two directories that have the same structure (don't hardcode what you can pass in as a parameter).

eestrada
  • 1,575
  • 14
  • 24