I have a file structure as shown in the figure. In total i have 9 folders, each folder holds 130 number of video files. I want to move the 1st video file of all 9 folders into one new folder "folder 01", and so on. Since, the first video file of all folders will have same name, how can i solve this problem? I need some insights into solving this?
3 Answers
The following code will perform the task. I've made the assumption that the base folder for the destination path is the same as the current path.
#!/usr/bin/env python3
import os
import shutil
base_folder = os.getcwd()
# Create 130 destination folders (folder_001, ..., folder_130)
dest_folder_prefix = "folder_"
dest_path = base_folder # An assumption
dest_paths = {}
for n in range(1, 131):
folder_number = str(n).zfill(3)
dest_folder = os.path.join(dest_path, f'{dest_folder_prefix}{folder_number}')
if not os.path.isdir(dest_folder):
os.mkdir(dest_folder)
# Store paths for quick lookup later
dest_paths[n] = dest_folder
# Iterate through the existing folders
src_folders = sorted([f for f in os.listdir(base_folder) if os.path.isdir(f)])
for n, folder_name in enumerate(src_folders, 1):
folder_number = str(n).zfill(2) # Used to rename destination file
folder_path = os.path.join(base_folder, folder_name)
# Process the list of files
files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))]
for file_name in files:
name, ext = os.path.splitext(file_name) # e.g. '1', '.avi' for file '1.avi'
file_number = int(name) # file name is a number
# Set the source
src_path = os.path.join(folder_path, file_name)
# Set the destination filename and path
dest_filename = f'{name}_{folder_number}{ext}' # Destination file name e.g. '1_01.avi'
dest_filepath = os.path.join(dest_paths[file_number], dest_filename)
# Perform the move operation
shutil.move(src_path, dest_filepath)
4 Comments
Lakpa Tamang
Thanks, works well. But what if we want to move sub-folders instead of files.
Dan Nagle
It's the same process for moving subfolders, you would need to remove the file specific portions of the code.
shutil.move() recursively moves both files and folders. Read the documentation for more information. docs.python.org/3/library/shutil.html#shutil.moveLakpa Tamang
If we need to reverse the process, then what could be the approach. What do you think?
Dan Nagle
It would essentially be the same process. Iterate through the list of files in each of the 130 folders. The filename contains the information you need:
{name}_{folder_number}{ext}, from this string you can determine the original folder and the original filename. Try it by repurposing the code provided in this answer.Python has a great function called os.walk() that does a lot of this for you.
You can do
for subdir, dirs, files in os.walk(rootdir):
for file in files:
print(file)
Which will print ALL of the files in the directory and subdirectories, then using this you can implement a check and use os.rename to rename the files accordingly.
Comments
y can use shutil
import shutil
original = r'C:\Users\Ron\Desktop\Test_1\products.csv'
target = r'C:\Users\Ron\Desktop\Test_2\products.csv'
shutil.copyfile(original, target)
i can give you a hint ! don't hesitate to ask for clarifications
def locate_path_by_substring(directory, substring, list_paths):
for r, d, f in os.walk(directory):
for myfile in f:
if (substring+".log") in myfile:
list_paths.append(os.path.join(r, myfile))
return list_paths
`
def copy_file(original,target):
shutil.copyfile(original, target)
def create_direct(path):
try:
os.mkdir(path)
except OSError:
print ("Creation of the directory %s failed" % path)
def main():
for i in range (1,131):
locate_path_by_substring(directory, i, list_file_{}.format(i))
create_direct(directory+"/folder_{}".format(i))
for i in range (1,131):
for j in range (0,9):
copy_file(list_file_{i}[j],directory+"/folder_{}".format(i)/)`

shutilto copy the files. However for the logic ... you will have to figure that out yourself. Shouldn't be too hard.