sorting for recursive folder rename

I

ianaré

Hello all,

I trying to recursively rename folders 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[0] = self.toRename[0].replace(oF,nF)
self.toRename[1] = self.toRename[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)



First problem is adjusting the paths can take a very long time.
Second problem is sorting is not always right and files get lost !!
Any input welcome.
 
M

MRAB

ianaré said:
Hello all,

I trying to recursively rename folders 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: if not item[2]:
oF = split(item[0])[1] # original folder name
nF = split(item[1])[1] # new folder name
if oF is not nF: if oF != 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[0] = self.toRename[0].replace(oF,nF)
self.toRename[1] = self.toRename[1].replace(oF,nF)

if progressDialog.update(i) is False:

if not progressDialog.update(i):
error = 'cancelled'
break

# make sure renaming will be in correct order !
self.toRename.sort(recursiveFolderSort)



First problem is adjusting the paths can take a very long time.
Second problem is sorting is not always right and files get lost !!
Any input welcome.
You should use "is" and "is not" _only_ when checking for _identity, ie
are these 2 both references to the _same_ object. Most of the time that
would be "x is None" or "x is not None".
 
I

ianaré

ianaré said:
Hello all,
I trying to recursively rename folders 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:

      if not item[2]:>         oF = split(item[0])[1] # original folder name
        nF = split(item[1])[1] # new folder name
        if oF is not nF:

          if oF != 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[0] = self.toRename[0].replace(oF,nF)
        self.toRename[1] = self.toRename[1].replace(oF,nF)

    if progressDialog.update(i) is False:

      if not progressDialog.update(i):>         error = 'cancelled'
        break
# make sure renaming will be in correct order !
self.toRename.sort(recursiveFolderSort)
First problem is adjusting the paths can take a very long time.
Second problem is sorting is not always right and files get lost !!
Any input welcome.

You should use "is" and "is not" _only_ when checking for _identity, ie
are these 2 both references to the _same_ object. Most of the time that
would be "x is None" or "x is not None".


Thanks, this has been corrected.
 
R

Rhodri James

Hello all,

I trying to recursively rename folders 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]
..
]

[snip]

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.
 
I

ianaré

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[0] = self.toRename[0].replace(oF,nF)
self.toRename[1] = self.toRename[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.

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.

Solution finder will have his/her name placed on the credits page.
http://file-folder-ren.sourceforge.net/index.php?page=Links

Thanks in advance !!
 
P

Peter Otten

ianaré said:
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[0] = self.toRename[0].replace(oF,nF)
self.toRename[1] = self.toRename[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.

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top