How to move files stored in a directory and its subdirectories to a different directory?

Question:

I have a ton of images stored in many subdirectories that need to be moved to a single directory. Many of these files have the exact same name, even though they may be present in different subdirectories.

I have tried this, and it works perfectly. However, it is not able to access the files stores in subdirectories. What changes can I make so that it moves the files from subdirectories as well.

import os
import shutil
import datetime
import glob

now = str(datetime.datetime.now())
now = now.replace(":","")
count = 1

dirr = 'path'
move = '/path_to_directory_where_the_files_are_to_be_moved'
for files in os.listdir(dirr): 
    if files.endswith('20.jpg') or files.endswith('29.jpg'):
        src = dirr + files
        dst = move + files+str(now)+'.jpg'
        shutil.copy(src, dst)
        print("copied " + str(count) +' files n')
        count +=1

I finally got it working, and I have shared the final code below.

import os
import shutil
import datetime
import glob
import time
count = 1

dirr = 'path'
move = '/path_to_directory_where_the_files_are_to_be_moved'

for files in glob.glob(dirr + '/**', recursive=True):
    if files.endswith('20.jpg') or files.endswith('29.jpg'):
        now = str(datetime.datetime.now())
        now = now.replace(":","")
        print(files)
        files1 = os.path.basename(files)
        src = dirr + files1
        dst = move + files1+str(now)+'.jpg'
        #print(src, dst)
        shutil.copy(files, dst)
        #time.sleep(0.05) ## use only when you want to make absolutely sure that each file gets a unique name when it is being copied. You won't need it anyway, but just in case
        print("copied " + str(count) +' files n')
        count +=1
Asked By: NUI

||

Answers:

You should use walk (Documentation)

import os


def file_filter(filename: str) -> bool:
    ...


def copy_file(filename: str, src_folder: str, dst_folder: str):
    ...


src = 'path'
dst = 'dst_path'

i = 0
for root, dirs, files in os.walk(src):
    for f in filter(file_filter, files):
        copy_file(f, root, dst)
        i += 1
Answered By: cestlarumba

Since you have already imported glob, let’s put it to use, the for loop here is a replacement of the for loop you are using but it gets all the files in the subdirectories:

import os
import shutil
import datetime
import glob

now = str(datetime.datetime.now())
now = now.replace(":","")
count = 1

dirr = 'path'
move = '/path_to_directory_where_the_files_are_to_be_moved'

for files in glob.iglob('path' + '**/**', recursive=True):
    files = os.path.basename(files)  # This is to get the file name without the directory name attached to it
    if files.endswith('20.jpg') or files.endswith('29.jpg'):
        src = dirr + files
        dst = move + files+str(now)+'.jpg'
        shutil.copy(src, dst)
        print("copied " + str(count) +' files n')
        count +=1
Answered By: nomans_
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.