Python rename files reading names from csv file

10,772

Solution 1

This will rename each matching file, and report any errors trying to rename. It will not attempt to move non-existent files.

import os, unicodecsv as csv
# open and store the csv file
IDs = {}
with open('documentos_corpus_ladino.csv','rb') as csvfile:
    timeReader = csv.reader(csvfile, delimiter = ',')
    # build dictionary with associated IDs
    for row in timeReader:
        IDs[row[0]] = row[1]
# move files
path = 'txt_orig/'
tmpPath = 'txt_tmp/'
for oldname in os.listdir(path):
    # ignore files in path which aren't in the csv file
    if oldname in IDs:
        try:
            os.rename(os.path.join(path, oldname), os.path.join(tmpPath, IDs[oldname]))
        except:
            print 'File ' + oldname + ' could not be renamed to ' + IDs[oldname] + '!'

Solution 2

You're iterating on the file and store old and new names in IDs but don't use it and just try to read further from the file (which will fail obviously since you've already read the whole file by that time). IOW you should use your IDs dict to get new names (using the oldname as key) instead, ie:

path = 'txt_orig' # no trailing slash required
tmpPath = 'txt_tmp' # idem
for filename in os.listdir(path):
    try:
       newname = IDs[filename]
    except KeyError:
       print "no new name for '%s'" % filename
       continue
    else:     
        os.rename(os.path.join(path, filename), os.path.join(tmpPath, newname))

Now there's a much simpler solution: just rename the files as you iterate on the csv file:

path = 'txt_orig'
tmp_path = 'txt_tmp'
with open('documentos_corpus_ladino.csv','rb') as csvfile:
    reader = csv.reader(csvfile, delimiter = ',')
    for row in reader:
       oldname = os.path.join(path, row[0])
       if os.path.exists(oldname):
           newname = os.path.join(tmp_path, row[1])
           os.rename(oldname, newname)
           print >> sys.stderr, "renamed '%s' to '%s'" % (oldname, newname)
       else:
           print >> sys.stderr, "file '%s' not found" % oldname
Share:
10,772
Andrés Chandía
Author by

Andrés Chandía

Chileno

Updated on June 07, 2022

Comments

  • Andrés Chandía
    Andrés Chandía 7 months

    Hi there i've been trying to adapt this to my needs but I'm just a newbe in python, I have a csv file with multiple columns and rows, important columns are 1 = old name of file, and 2 = new name of file, so I need to go the directory where the files listed in csv file are and rename them to the new name of column 2, as I say I've tried many things without success, I paste the last code I've made so you have an idea:

    import os, unicodecsv as csv, sys
    IDs = {}
    #open and store the csv file
    with open('documentos_corpus_ladino.csv','rb') as csvfile:
            timeReader = csv.reader(csvfile, delimiter = ',')
            # build a dictionary with the associated IDs
            for row in timeReader:
                  IDs[ row[0] ] = row[1]
    # #get the list of files
    path = 'txt_orig/'
    tmpPath = 'txt_tmp/'
    for filename in os.listdir('txt_orig/'):
        oldname = filename
        newname = filename.replace(oldname, csvfile.next().rstrip().split(",")[1])
        os.rename(path + filename, tmpPath + newname)
    

    Thanks a lot.

  • Andrés Chandía
    Andrés Chandía about 9 years
    Thanks a lot, your first code give error when a file name contains characters like ñ or ç, but the second one works great. Anyway how could I copy the files instead of moving them, I mean keeping the original file?
  • Andrés Chandía
    Andrés Chandía about 9 years
    Thanks a lot it works great. Anyway how could I copy the files instead of moving them, I mean keeping the original file?
  • Pi Marillion
    Pi Marillion about 9 years
    @AndrésChandía Sure, just use shutil.copy(source, dest) instead of os.rename(source, dest) to copy file instead of moving.
  • Andrés Chandía
    Andrés Chandía about 9 years
    Don't work, for all the files it says "could not be renamed to", this is what i put: shutil.copy(os.path.join(path, oldname), os.path.join(destPath, IDs[oldname]))
  • Pi Marillion
    Pi Marillion about 9 years
    That sounds like a permissions issue, either with the file being replaced or the file being copied. If it's with the file being copied, then using shutil.copyfile, which doesn't copy permissions, may work.
  • Andrés Chandía
    Andrés Chandía about 9 years
    Sorry, still not working, the code: IDs = {} with open('documentos_corpus_ladino.csv','rb') as csvfile: timeReader = csv.reader(csvfile, delimiter = ',') for row in timeReader: IDs[row[0]] = row[1] path = 'txt_orig/' destPath = 'txt/' for oldname in os.listdir(path): if oldname in IDs: try: shutil.copyfile(os.path.join(path, oldname), os.path.join(destPath, IDs[oldname])) except: print 'File ' + oldname + ' could not be renamed to ' + IDs[oldname] + '!'
  • Andrés Chandía
    Andrés Chandía about 9 years
    Ok, all the problem was that I had to import shutil also, thanks a lot