Search code examples
pythonglobsubdirectoryos.walklistdir

How to walk through subfolders individually?


Actually I have a folder (data in below picture) which contains 2 subfolders and each subfolder includes some .png files. I need to have loop through each subfolder and do some coding on each image file in that subfolder and save the result. I have used os.walk() and os.listdir() and glob.glob() but none of them worked. One of many codes that I have tried is same as below:

path1 = Path('./data')
path2 = os.listdir(path1)

# loop through main folder to read each subfolder
for i in path2:
    if not i.startswith('.'):
       path3 = Path(os.path.join(path1,i))
       path4 = os.listdir(path3)

    #loop through each subfolder to read each file
       for j in path4:
           #some coding

enter image description here

Any suggestion would be highly appreciated.


Solution

  • Something like this with os.walk:

    import os
    for root, dirs, files in os.walk(path_to_data_folder):
    #    if not root.endswith(good_folder_name):
    #        continue
        for fname in files:
            if fname_meets_my_criteria:
                fpath = os.path.join(root, fname)
                with open(fpath, 'r') as f, open(new_file_path, 'w') as newfile:
                    data = f.read()
                    # process file data
                    new_data = func_that_processes_data(data)
                    newfile.write(new_data)
    

    That has a bit of pseudocode:

    • fname_meets_my_criteria is a substitute for a comparison, it needs this if you want to filter the files for processing - it could be something like fname.edswith('.txt') or not fname.endswith('.cfg')

    • new_file_path is the path and name for a new file that the processed data would be written to.


    If you intend to overwrite the files after they have been processed use this instead:

    for root, dirs, files in os.walk(path_to_data_folder):
    #    if not root.endswith(good_folder_name):
    #        continue
        for fname in files:
            if fname_meets_my_criteria:
                fpath = os.path.join(root, fname)
                with open(fpath, 'r') as f:
                    data = f.read()
                # process file data
                new_data = func_that_processes_data(data)
                with open(fpath, 'w') as f:
                    f.write(new_data)
    

    In both of my examples, the files were opened as Text files. If you need to process bytes instead of test/strings open the files with mode arguments of 'rb' or 'wb'