0
import os
import shutil
source_dir = r'C:\\Users\\Andre\\Downloads'
image_dir = r'C:\\Users\\Andre\\Downloads\\images'

file_names = os.listdir(source_dir)
    
for file_name in file_names:
    if '.png' in file_name:
        shutil.move(os.path.join(source_dir, file_name), image_dir)

This current code will move all pngs from source dir to image dir, how can I make it so it also includes pngs nested in another subdirectory inside the source dir? for example C:\Users\Andre\Downloads\pictures

tripleee
  • 175,061
  • 34
  • 275
  • 318
Andyw3
  • 90
  • 1
  • 5
  • 1
    If you use raw strings, you don't have to double the backslashes. – tripleee Oct 18 '20 at 17:21
  • Do you want to preserve subdirectory nesting, or have all the files go directly into the 'images' dir? – CryptoFool Oct 18 '20 at 17:31
  • Does this answer your question? [Python 3: search subdirectories for a file](https://stackoverflow.com/questions/41191864/python-3-search-subdirectories-for-a-file) OR https://stackoverflow.com/questions/18394147/recursive-sub-folder-search-and-return-files-in-a-list-python – Tomerikoo Oct 18 '20 at 17:34
  • @Steve the latter, all going to straight to images dir. – Andyw3 Oct 18 '20 at 17:55
  • @Tomerikoo i have tried doing an os.walk and it does indeed return all the png files in both the main folder and the subdirectory, but the problem i have with that is that it doesn't change the working directory so when I try to move the file it assumes the source dir. – Andyw3 Oct 18 '20 at 17:56
  • But it gives you the root also... `for root,subs,files in os.walk(...): for file in files: print(os.path.join(root, file))` – Tomerikoo Oct 19 '20 at 07:11

2 Answers2

0

You can break the moving functionality into a function, then call that function on each directory.

def move_pngs(src, dst):
    for file_name in os.listdir(src):
        if file_name.endswith('.png'):
            shutil.move(os.path.join(src, file_name), dst)

move_pngs(source_dir, image_dir)
move_pngs(os.path.join(source_dir, 'pictures'), image_dir)

... Or maybe go full recursive.

def move_pngs(src, dst):
    for file_name in os.listdir(src):
        fullname = os.path.join(src, file_name)
        if os.path.isdir(fullname) and fullname != dst:
            move_pngs(fullname, dst)
        elif file_name.endswith('.png'):
            shutil.move(fullname), dst)

This will visit all subdirectories recursively, and move all files into one flat directory, meaning if there are files with the same names anywhere, generally the one from a deeper subdirectory will win, and the others will be overwritten.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • thanks, using the second code snippet I think there is a problem where its trying to move all the files already in the image directory and then failing because they already exist there, is there a way to avoid that? – Andyw3 Oct 18 '20 at 17:57
  • `if os.path.isdir(fullname) and fullname != to:` probably. – tripleee Oct 18 '20 at 18:45
0

You can simply just change the source_dir to also include the subdirectory which you want to move the pngs from and run then the loop again.
In this case:

subdirectory = '\pictures'
source_dir += subdirectory 

file_names = os.listdir(source_dir)    
for file_name in file_names:
    if '.png' in file_name:
        shutil.move(os.path.join(source_dir, file_name), image_dir)
void main
  • 123
  • 7