pythonsubdirectoryshutilscandir

trying to move files from many different subfolders to a main subfolder


I am working on a program to organise all files in my downloads folder. For that I am trying to move every file in every subdirectory in my downloads folder to a new folder called "all files". What I don't understand is, that I can access the files in the subfolders (and print them for instance), but I cannot move them. I get the following error instead:

Traceback (most recent call last):

  File "C:\Users\My Username\Desktop\Desktop\Python\testing\147_file_organizer.py", line 33, in <module>
    shutil.move(subfolder_path, dst_path)

  File "D:\anaconda3\lib\shutil.py", line 801, in move
    if _samefile(src, dst):

  File "D:\anaconda3\lib\shutil.py", line 220, in _samefile
    return os.path.samefile(src, dst)

  File "D:\anaconda3\lib\genericpath.py", line 100, in samefile
    s1 = os.stat(f1)

TypeError: stat: path should be string, bytes, os.PathLike or integer, not list

Here is the code:

import os
import shutil


path = ('C:/Users/My Username/Downloads/')
obj = os.scandir(path)

for entry in obj:
    dst_path = r'C:/Users/My Username/Downloads/all files/'
    if entry.is_dir():
        subfolder_path = os.listdir(path + entry.name)
        for subfolder_file in subfolder_path:
            shutil.move(subfolder_path, dst_path)

obj.close()

Thank you very much for your tips, help and suggestions of any kind!


Solution

  • I think this is caused by a simple typo. You are trying to perform a shutil.move on subfolder_path - a list of all files/dirs under the entry path instead of subfolder_file - the files/dirs within the list you are iterating over within the for loop.

    Additionally however, you probably want to be specifying a full path rather than just the base name of the files/dirs you are moving, which is what is returned by os.listdir

    Instead you want:

    for entry in obj:
        dst_path = r'C:/Users/My Username/Downloads/all files/'
        if entry.is_dir():
            subfolder_path = os.listdir(path + entry.name)
            for subfolder_file in subfolder_path:
                shutil.move(os.path.join(entry.path, subfolder_file), dst_path)