Recursively move all files on subdirectories to another directory in Python
Question:
The title explains what I am after. Note that the sub directories won’t contain any directories only files (*.JPG). Essentially, just moving everything up one level in the file tree.
For example, from ~/someDir/folder1/*
, ~/someDir/folder2/*
, … , ~/someDir/folderN/*
. I want all of the contents of the sub directories brought up to ~/someDir/
.
Answers:
shutil.move is a good option to move files.
import shutil
import os
source = "/parent/subdir"
destination = "/parent/"
files_list = os.listdir(source)
for files in files_list:
shutil.move(files, destination)
For Recursive move, you can try shutil.copytree(SOURCE, DESTINATION)
. it just copies all files and if needed you can manually cleanup the source directory.
Also, You can achieve something similar using Pathlib
.
from pathlib import Path
def _move_all_subfolder_files_to_main_folder(folder_path: Path):
"""
This function will move all files in all subdirectories to the folder_path dir.
folder_path/
1/
file1.jpg
file2.jpg
2/
file4.jpg
outputs:
folder_path/
file1.jpg
file2.jpg
file4.jpg
"""
if not folder_path.is_dir():
return
for subfolder in folder_path.iterdir():
for file in subfolder.iterdir():
file.rename(folder_path / file.name)
Usage would be:
_move_all_subfolder_files_to_main_folder(Path('my_path_to_main_folder'))
Use this, if the files have same names, new names will have folder names joined by ‘_’
import shutil
import os
source = 'path to folder'
def recursive_copy(path):
for f in sorted(os.listdir(os.path.join(os.getcwd(), path))):
file = os.path.join(path, f)
if os.path.isfile(file):
temp = os.path.split(path)
f_name = '_'.join(temp)
file_name = f_name + '_' + f
shutil.move(file, file_name)
else:
recursive_copy(file)
recursive_copy(source)
Here is modified way of doing along with a duplicate check:
src = r'D:TestSourceFolder'
dst = r'D:TestDestFolder'
for root, subdirs, files in os.walk(src):
for file in files:
path = os.path.join(root, file)
print("Found a file: "+path)
print("Only name of the file: "+file)
print("Will be moved to: "+os.path.join(dst, file))
# If there is no duplicate file present, then move else don't move
if not os.path.exists(os.path.join(dst, file)):
#shutil.move(path, os.path.join(dst, os.path.relpath(path, src)))
shutil.move(path, os.path.join(dst, file) )
print("1 File moved : "+file+"n")
else:
print("1 File not moved because duplicate file found at: "+path+"n")
The title explains what I am after. Note that the sub directories won’t contain any directories only files (*.JPG). Essentially, just moving everything up one level in the file tree.
For example, from ~/someDir/folder1/*
, ~/someDir/folder2/*
, … , ~/someDir/folderN/*
. I want all of the contents of the sub directories brought up to ~/someDir/
.
shutil.move is a good option to move files.
import shutil
import os
source = "/parent/subdir"
destination = "/parent/"
files_list = os.listdir(source)
for files in files_list:
shutil.move(files, destination)
For Recursive move, you can try shutil.copytree(SOURCE, DESTINATION)
. it just copies all files and if needed you can manually cleanup the source directory.
Also, You can achieve something similar using Pathlib
.
from pathlib import Path
def _move_all_subfolder_files_to_main_folder(folder_path: Path):
"""
This function will move all files in all subdirectories to the folder_path dir.
folder_path/
1/
file1.jpg
file2.jpg
2/
file4.jpg
outputs:
folder_path/
file1.jpg
file2.jpg
file4.jpg
"""
if not folder_path.is_dir():
return
for subfolder in folder_path.iterdir():
for file in subfolder.iterdir():
file.rename(folder_path / file.name)
Usage would be:
_move_all_subfolder_files_to_main_folder(Path('my_path_to_main_folder'))
Use this, if the files have same names, new names will have folder names joined by ‘_’
import shutil
import os
source = 'path to folder'
def recursive_copy(path):
for f in sorted(os.listdir(os.path.join(os.getcwd(), path))):
file = os.path.join(path, f)
if os.path.isfile(file):
temp = os.path.split(path)
f_name = '_'.join(temp)
file_name = f_name + '_' + f
shutil.move(file, file_name)
else:
recursive_copy(file)
recursive_copy(source)
Here is modified way of doing along with a duplicate check:
src = r'D:TestSourceFolder'
dst = r'D:TestDestFolder'
for root, subdirs, files in os.walk(src):
for file in files:
path = os.path.join(root, file)
print("Found a file: "+path)
print("Only name of the file: "+file)
print("Will be moved to: "+os.path.join(dst, file))
# If there is no duplicate file present, then move else don't move
if not os.path.exists(os.path.join(dst, file)):
#shutil.move(path, os.path.join(dst, os.path.relpath(path, src)))
shutil.move(path, os.path.join(dst, file) )
print("1 File moved : "+file+"n")
else:
print("1 File not moved because duplicate file found at: "+path+"n")