sorting for recursive folder rename
Peter Otten
__peter__ at web.de
Fri Feb 6 07:02:12 EST 2009
ianaré wrote:
> On Dec 16 2008, 7:36 pm, "Rhodri James" <rho... at wildebst.demon.co.uk>
> wrote:
>> On Tue, 16 Dec 2008 18:20:52 -0000, ianaré <ian... at gmail.com> wrote:
>> > Hello all,
>>
>> > I trying to recursivelyrenamefolders and files, and am looking for
>> > some ideas on the best way of doing this. The problem is that the
>> > given list of items can be in order, and one to all items may be
>> > renamed. Here is some preliminary code I have, but which does not work
>> > very well.
>
> self.toRename has the following structure :
> [
> [original_name, new_name, os.path.isdir]
> ..
> ]
>
> # define these here for faster processing
> def split(item):
> return os.path.split(item)
> def addSep(path):
> return os.sep + path + os.sep
> def recursiveFolderSort(x,y):
> return cmp(y[0], x[0])
>
> sortedRename = sorted(self.toRename)
>
> # make a list of all folders that will be processed
> foldersToAdjust = []
> for item in sortedRename:
> if item[2] is False:
> oF = split(item[0])[1] # original folder name
> nF = split(item[1])[1] # new folder name
> if oF is not nF:
> foldersToAdjust.append((oF, nF))
>
> # replace all occurences of folders in path
> for i in range(len(self.toRename)):
> for f in foldersToAdjust:
> oF = addSep(f[0]) # original folder name
> nF = addSep(f[1]) # new folder name
> self.toRename[i][0] = self.toRename[i][0].replace(oF,nF)
> self.toRename[i][1] = self.toRename[i][1].replace(oF,nF)
>
> if progressDialog.update(i) is False:
> error = 'cancelled'
> break
>
> # make sure renaming will be in correct order !
> self.toRename.sort(recursiveFolderSort)
>
>> import os
>>
>> for item in self.toRename:
>> os.renames(item[0], item[1])
>>
>> That's it. os.renames will take care of all the intermediate
>> directory creation so you don't even need to sort the list.
>>
>> --
>> Rhodri James *-* Wildebeeste Herder to the Masses
>
> It's been a while since I decided to work on this again ...
>
> Anyway, if only it were that easy !!
>
> Traceback (most recent call last):
> File "/home/ianare/Desktop/file-folder-ren/metamorphose2/Source/
> MainWindow.py", line 1477, in renameItems
> os.renames(original[0], renamed[0])
> File "/usr/lib/python2.5/os.py", line 213, in renames
> rename(old, new)
> OSError: [Errno 2] No such file or directory
>
>
> The problem is that if a directory is changed, all lower instances
> need to be changed as well.
>
> given the following directory structure ...
>
> recursive
> |
> |_1
> | |_1
> | | |_1.txt
> | | |_2.txt
> | |_2
> | |_1.txt
> | |_2.txt
> |_2
> |_1
> | |_1.txt
> | |_2.txt
> |_2
> |_1.txt
> |_2.txt
>
> ... and assuming I want to change :
> recursive/2/2/2.txt --> recursive/2/2/14.txt
>
> but, I ALSO want to change :
> recursive/2 --> recursive/04
>
> it means that the first operation is really :
> recursive/04/2/2.txt --> recursive/04/2/14.txt
>
> os.renames will work, but it needs to have the correct path, so it
> comes down to the same thing.
>
> IOW, I need a way of :
> A) adjusting paths taking into consideration all changes up and down
> the tree
> B) sorting normalized paths so they are renamed in the proper sequence
> (depends on point 'A', obviously)
>
> I'm pretty sure I can take care of 'B' with the following sorting
> method:
>
> # order by path depth
> def recursiveFolderSort(x, y):
> x = x[0].count(os.sep)
> y = y[0].count(os.sep)
> return cmp(x, y)
> self.toRename.sort(recursiveFolderSort)
>
> but I still need a way of generating the correct names.
I don't see the problem. Just rename the deepest files and directories
first.
# untested
def old_depth((old, new)):
p = os.path.abspath(old)
return p.count(os.sep) - p.endswith(os.sep) # don't count trailing slash
pairs = sorted(self.toRename, key=old_depth, reverse=True)
for old, new in pairs:
os.rename(old, new)
Because "recursive/2/2/2.txt" has more slashes it will be processed
before "recursive/2" and thus when the latter is processed the former's
path will change implicitly.
Peter
More information about the Python-list
mailing list