Reputation: 776
I want to rename all the files in subfolders of two parent directories replacing spaces with underscores. This is my structure:
parent folder
folder 1
TIFF
image 1
image 2
[...]
folder 2
TIFF
image 1
image 2
[...]
[...]
This is the result I want:
parent folder
folder_1
TIFF
image_1
image_2
[...]
folder_2
TIFF
image_1
image_2
[...]
[...]
This is the script that I'm using and which so far is not doing anything:
#!/usr/local/bin/python3
import os
def replace(parent):
for path, folders, files in os.walk(parent):
for i in range(len(folders)):
os.chdir("TIFF")
for f in files:
os.rename(os.path.join(path, f), os.path.join(path, f.replace(' ', '_')))
new_name = folders[i].replace(' ', '_')
os.rename(os.path.join(path, folders[i]), os.path.join(path, new_name))
folders[i] = new_name
What am I overlooking?
Upvotes: 0
Views: 1461
Reputation: 189377
Doing os.chdir()
inside os.walk()
is almost certainly wrong.
Also, take care to not rename parent directories whilst you are traversing their children.
#!/usr/local/bin/python3
import os
def replace(parent):
remembrance = []
for path, folders, files in os.walk(parent):
if os.path.basename(path) == "TIFF":
for f in files:
os.rename(os.path.join(path, f), os.path.join(path, f.replace(' ', '_')))
elif "TIFF" in folders:
remembrance.append((path, os.path.join(os.path.dirname(path), os.path.basename(path).replace(" ", "_"))))
for src, dst in remembrance:
os.rename(src, dst)
Your code never calls replace()
so perhaps that's the first thing you are missing, though. Declaring a function just tells Python what to do if and when you call that function later on.
If you don't need to recurse really, just do
import os
import glob
def underscorify(path):
os.rename(path, os.path.join(os.path.dirname(path), os.path.basename(path).replace(" ", "_"))
for file in glob.glob("*/TIFF/*"):
underscorify(file)
for dirname in glob.glob("*/"):
if os.path.exists(os.path.join(dirname), "TIFF"):
underscorify(dirname)
Upvotes: 0
Reputation: 21
when you using os.chdir
method,because your working directory is always changing,you should use os.getcwd
to see the current working directory,you will know what's wrong,and then change the working directory to parent first,then you can change it as you wish.
Upvotes: 0
Reputation: 2159
You are probably running in the issue where you have renamed a folder, before the os.walk
has finished walking through it. This can be solved by setting topdown=False
. Now you will first receive the lowest files, and folders.
Then you can update the files first and then the folders.
import os
def rename(path, file):
old_file = os.path.join(path, file)
new_file = os.path.join(path, file.replace(' ', '_'))
os.rename(old_file, new_file)
def replace(parent):
for path, folders, files in os.walk(parent, topdown=False):
print(path, folders, files)
for file in files:
rename(path, file)
for folder in folders:
rename(path, folder)
The following structure and code was used to test the script:
└───parent
├───folder 1
│ └───TIFF
│ ├─── file 1.txt
│ └─── file 2.txt
├───folder 2
│ └───TIFF
│ ├─── file 1.txt
│ └─── file 2.txt
└─── main.py
main.py
import os
def rename(path, file):
old_file = os.path.join(path, file)
new_file = os.path.join(path, file.replace(' ', '_'))
os.rename(old_file, new_file)
def replace(parent):
for path, folders, files in os.walk(parent, topdown=False):
print(path, folders, files)
for file in files:
rename(path, file)
for folder in folders:
rename(path, folder)
if __name__ == '__main__':
parent = os.path.dirname(__file__)
replace(os.path.join(parent, 'parent'))
Upvotes: 1