/Users/amit/my-folder
├── folder1
│ ├── 1.jpg
│ ├── 2.jpg
│ ├── 3.jpg
│ ├── 4.jpg
│ ├── 5.jpg
│ ├── 6.jpg
│ ├── 7.png
│ ├── 8.jpg
│ └── 9.jpg
├── folder2
│ ├── 1.gif
│ ├── 2.jpg
│ ├── 3.jpg
│ ├── 4.jpg
│ └── 5.jpg
└── folder3
├── 1.jpg
├── 2.jpg
├── 3.jpg
└── 4.jpg
The immediate concern we have with flattening the directory tree above is that we will have clashes with filenames so we need to write something that can handle that.
The function below will flatten a multi-level directory and move all files to the root directory deleting all sub-folders in the process. Any files with the same name will have a count appended to their filename. Eg. 1_1.jpg
.
import os
import shutil
def flatten(directory):
for dirpath, _, filenames in os.walk(directory, topdown=False):
for filename in filenames:
i = 0
source = os.path.join(dirpath, filename)
target = os.path.join(directory, filename)
while os.path.exists(target):
i += 1
file_parts = os.path.splitext(os.path.basename(filename))
target = os.path.join(
directory,
file_parts[0] + "_" + str(i) + file_parts[1],
)
shutil.move(source, target)
print("Moved ", source, " to ", target)
if dirpath != directory:
os.rmdir(dirpath)
print("Deleted ", dirpath)
flatten(os.path.dirname("/Users/amit/my-folder"))
/Users/amit/my-folder
├── 1.gif
├── 1.jpg
├── 1_1.jpg
├── 2.jpg
├── 2_1.jpg
├── 2_2.jpg
├── 3.jpg
├── 3_1.jpg
├── 3_2.jpg
├── 4.jpg
├── 4_1.jpg
├── 4_2.jpg
├── 5.jpg
├── 5_1.jpg
├── 6.jpg
├── 7.png
├── 8.jpg
└── 9.jpg