Denver Dang Denver Dang -3 years ago 122
Python Question

Rename multiple files inside multiple folders

So I have a lot of folders with a certain name. In each folder I have +200 items. The items inside the folders has names like:

CT.34562346.246.dcm
RD.34562346.dcm
RN.34562346.LAO.dcm


And some along that style.

I now wish to rename all files inside all folders so that the number (34562346) is replaced with the name of the folder. So for example in the folder named "1" the files inside should become:

CT.1.246.dcm
RD.1.dcm
RN.1.LAO.dcm


So only the large number is replaced. And yes, all files are similar like this. It would be the number after the first . that should be renamed.

So far I have:

import os

base_dir = "foo/bar/" #In this dir I have all my folders

dir_list = []
for dirname in os.walk(base_dir):
dir_list.append(dirname[0])


This one just lists the entire paths of all folders.

dir_list_split = []
for name in dir_list[1:]: #The 1 is because it lists the base_dir as well
x = name.split('/')[2]
dir_list_split.append(x)


This one extracts the name of each folder.

And then the next thing would be to enter the folders and rename them. And I'm kind of stuck here ?

Answer Source

The pathlib module, which was new in Python 3.4, is often overlooked. I find that it often makes code simpler than it would otherwise be with os.walk.

In this case, .glob('**/*.*') looks recursively through all of the folders and subfolders that I created in a sample folder called example. The *.* part means that it considers all files.

I put path.parts in the loop to show you that pathlib arranges to parse pathnames for you.

I check that the string constant '34562346' is in its correct position in each filename first. If it is then I simply replace it with the items from .parts that is the next level of folder 'up' the folders tree.

Then I can replace the rightmost element of .parts with the newly altered filename to create the new pathname and then do the rename. In each case I display the new pathname, if it was appropriate to create one.

>>> from pathlib import Path
>>> from os import rename
>>> for path in Path('example').glob('**/*.*'):
...     path.parts
...     if path.parts[-1][3:11]=='34562346':
...         new_name = path.parts[-1].replace('34562346', path.parts[-2])
...         new_path = '/'.join(list(path.parts[:-1])+[new_name])
...         new_path
...         ## rename(str(path), new_path)
...     else:
...         'no change'
... 
('example', 'folder_1', 'id.34562346.6.a.txt')
'example/folder_1/id.folder_1.6.a.txt'
('example', 'folder_1', 'id.34562346.wax.txt')
'example/folder_1/id.folder_1.wax.txt'
('example', 'folder_2', 'subfolder_1', 'ty.34562346.90.py')
'example/folder_2/subfolder_1/ty.subfolder_1.90.py'
('example', 'folder_2', 'subfolder_1', 'tz.34562346.98.py')
'example/folder_2/subfolder_1/tz.subfolder_1.98.py'
('example', 'folder_2', 'subfolder_2', 'doc.34.34562346.implication.rtf')
'no change'
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download