简体   繁体   中英

Rename files in subfolders with python and os.walk()

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?

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)

Edit

The following structure and code was used to test the script:

  • Folder structure
└───parent
    ├───folder 1
    │   └───TIFF
    │         ├─── file 1.txt
    │         └─── file 2.txt
    ├───folder 2
    │    └───TIFF
    │         ├─── file 1.txt
    │         └─── file 2.txt
    └─── main.py
  • Code 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'))

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)

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM