How could I go about doing it? I have a big folder with a lot of sub-folders and files, I want to replace multiple specific folders and files with other folders and files stored somewhere else that contain the same file structure.
BigFolder
|
|--Folder 1
|--Folder 2
|--Folder 3
|--Folder 4
|--File 1
|--File 2
"Backup 1"
|
|--Folder 1
|--Folder 3
|--File 2
"Backup 2"
|
|--Folder 1
|--Folder 3
|--File 2
"Backup 3"
|
|--Folder 1
|--Folder 3
|--File 2
I put "backup" in quotes because it's not the real purpose of this, but for example purposes it works. So I should be able to grab the specific contents of the big folder and put them into one of the backups, then take another backup and grab its contents and drop them into the big folder, basically swapping them. How could I achieve this? I tried with shutil.copytree but that throws an error because the folder I'm copying into already exists, really dumb limitation. I also tried with distutils' copytree, but while it works, it doesn't copy the folders I want, just the contents, so it doesn't preserve the file structure.
import shutil
bigFolder = "/home/user/Big Folder"
def swapFiles(newFolder, prevFolder):
path = os.path
#Copy from big folder to the previous backup
shutil.copytree(path.join(bigFolder, "Folder 1"), prevFolder)
shutil.copytree(path.join(bigFolder, "Folder 3"), prevFolder)
shutil.copy(path.join(bigFolder, "File 2"), prevFolder)
#Copy from new folder to big folder
shutil.copytree(newFolder, bigFolder)
This doesn't work because it the destination folder already exists, it only works on non existing folder. With distutils:
from distutils.dir_util import copy_tree
import shutil
bigFolder = "/home/user/Big Folder"
def swapFiles(newFolder, prevFolder):
path = os.path
#Copy from big folder to the previous backup
copy_tree(path.join(bigFolder, "Folder 1"), prevFolder)
copy_tree(path.join(bigFolder, "Folder 3"), prevFolder)
shutil.copy(path.join(bigFolder, "File 2"), prevFolder) #shutil is fine here
#Copy from new folder to big folder
copy_tree(newFolder, bigFolder)
This doesn't work because it copies the contents of the folders and not the folder itself, so I don't keep the file structure.
By the way, in the middle of the two copying processes I should remove the files and folders to avoid merging with the newFolder's ones, but that's irrelevant to the question.
I found a solution, turns out shutil's stupid limitation of only being able to copy files to folders that don't exist was useful after all, but I also needed to use the copy_tree function from distutils, luckily they are both stdlib. First, create a list with all the files and folders you want to copy over as so:
filesToCopy = ["File 2", "Folder 1", "Folder 3"]
Then we need to create a couple of loops for each of the stages.
import shutil, os
from distutils.dir_util import copy_tree
def swapFiles(newDir, prevDir):
bigFolder = "Big Folder/Path"
#Copy from the big folder to the prevDir
for file in filesToCopy:
#Check if what you're about to copy is a directory
if os.path.isdir(os.path.join(bigFolder, file)):
copy_tree(os.path.join(bigFolder, file), os.path.join(prevDir, file))
else:
#If its a file, do a simple copy
shutil.copy(os.path.join(bigFolder, file), os.path.join(prevDir, file))
#Remove the copies folders from the big folder
for file in filesToCopy:
if os.path.isdir(os.path.join(bigFolder, file)):
shutil.rmtree(os.path.join(bigFolder, file))
else:
os.remove(os.path.join(bigFolder, file))
#Copy over files from newDir to bigFolder
for file in filesToCopy:
if os.path.isdir(os.path.join(newDir, file)):
#I use shutil's copytree here because I want it to create the folders I deleted in the previous step
shutil.copytree(os.path.join(newDir, file), os.path.join(bigFolder, file))
else:
shutil.copy(os.path.join(newDir, file), os.path.join(bigFolder, file))
With this, the file structure is maintained, and it's really easy to specify which files and folders you want to swap.