paugrana :
I am trying to rename several directories with the name of the first file inside them.
I am trying to:
- List the files inside a folder.
- Identify the directories.
- For each directory, access it, grab the name of the first file inside and rename the directory with such name.
This is what I got so far but it is not working. I know the code is wrong but before fixing the code I would like to know if the logic is right. Can anyone help please?
import os
for (root, dirs, files) in os.walk('.'):
print(f'Found directory: {dirpath}')
dirlist = []
for d_idx, d in enumerate(dirlist):
print(d)
filelist = []
for f_idex, f in enumerate(filelist):
files.append(f)[1]
print(f)
os.rename(d, f)
Thank you!
jdehesa :
There are a few problems in your code:
- You are renaming directories as you iterate them with
os.walk
. This is not a good idea,os.walk
gives you a generator, meaning it creates elements as you iterate them, so renaming things within the loop will confuse it. - Both
for d_idx, d in enumerate(dirlist):
andfor f_idex, f in enumerate(filelist):
iterate over variables that are declared to be empty lists in the line before, so those loops don't do anything. Also, within the second one,files.append(f)
would appendf
to the listfiles
, but the[1]
at the end means "get the second element (remeber Python indexing is 0-based) of the value returned by theappend
function" - butappend
does not return anything (it modifies the list, not returns a new list), so that would fail (and you are not using the value read by[1]
anyway, so it would not do anything). - In
os.rename(d, f)
, first, since the loops before do not ever run,d
andf
will not have a value, but also, assuming bothd
andf
came fromdirs
andfiles
, they would be given as paths relative to their parents, not to your current directory (.
), so the renaming would fail.
This code should work as you want:
import os
# List of paths to rename
renames = []
# Walk current dir
for (root, dirs, files) in os.walk('.'):
# Skip this dir (cannot rename current directory)
if root == '.': continue
# Add renaming to list
renames.append((root, files[0]))
# Iterate renaming list in reverse order so deepest dirs are renamed first
for root, new_name in reversed(renames):
# Make new full dir name (relative to current directory)
new_full_name = os.path.join(os.path.dirname(root), new_name)
# Rename
os.rename(root, new_full_name)