Following on from this page about the os
and pathlib
modules, here’s how to cut and copy files in Python.
The code on this page uses the os
, pathlib
and shutil
modules which come pre-installed with Python. Import them into your script as follows:
import os
from pathlib import Path
import shutil
Next, create example files and folders that you can cut and copy:
# Create Folders
os.makedirs('Source Folder', exist_ok=True)
os.makedirs('Source Folder/Subfolder', exist_ok=True)
os.makedirs('Destination Folder', exist_ok=True)
# Create files
paths = [
'Source Folder/Example File.txt',
'Source Folder/Subfolder/Example File.txt'
]
for path in paths:
f = open(path, 'w+')
f.write('Hi, mom')
f.close()
Cutting-and-pasting a file is essentially the same as moving it which, in the opinion of your computer, is the same as renaming its location. As such, the function in Python that achieves this is rename()
from the os
module:
# Source file
src = 'Source Folder/Example File.txt'
# Destination file
dst = 'Destination Folder/Example File.txt'
# Check that the destination folder exists (create it if not)
os.makedirs('Destination Folder', exist_ok=True)
# Cut-and-paste
os.rename(src, dst)
# Move it back
os.rename(dst, src)
It might seem a bit weird that we’re using the rename()
function when the file in question is not being renamed, but that’s the way it is.
The following code will move all files in a folder and its sub-folders into a different folder (and into corresponding sub-folders inside that):
# Source folder
src_folder = 'Source Folder'
# Destination folder
dst_folder = 'Destination Folder'
# Walk through the filesystem
for dirpath, dirnames, filenames in os.walk(src_folder):
# Sort the dirnames to iterate over them in alphabetical order
dirnames.sort()
# Sort the filenames to iterate over them in alphabetical order
filenames.sort()
# Iterate over the files
for filename in filenames:
# Ignore hidden files
if filename.startswith('.'):
continue
# Only move one type of file
if not filename.endswith('.txt'):
continue
# Set the source path
src_path = Path(dirpath, filename)
# Only replace the first instance of the source folder's name
dst_dirpath = dirpath.replace(str(src_folder), dst_folder, 1)
dst_path = Path(dst_dirpath, filename)
# Check that the destination folder exists (create it if not)
os.makedirs(dst_dirpath, exist_ok=True)
# Move (which is actually a rename operation)
print(f'Moving "{src_path}" to "{dst_path}"')
os.rename(src_path, dst_path)
## Moving "Source Folder/Example File.txt" to "Destination Folder/Example File.txt"
## Moving "Source Folder/Subfolder/Example File.txt" to "Destination Folder/Subfolder/Example File.txt"
os.walk()
function will ‘walk’ through the source folder and all its sub-folders, finding all files contained within itsort()
method is optional; it merely causes the folders and files to be handled in alphabetical orderif...continue
block. This is done in the example above to skip hidden files (which are files that start with a full stop).if not...continue
block. This is done in the example above to ensure that only text files are moved.Path()
objects from the pathlib
module instead of string paths is optional but good practice: a variable that represents a path should be stored and handled in Python as a path objectos.makedirs()
function with the exist_ok
parameter set to True
to ensure that the folder(s) you want to move a file into either already exist or get created before the move is attemptedBecause I want this script to work every time I run it, the files should be moved back. This can be achieved by simply reversing the source and destination folders:
# Source folder
src_folder = 'Destination Folder'
# Destination folder
dst_folder = 'Source Folder'
# Walk through the filesystem
for dirpath, dirnames, filenames in os.walk(src_folder):
# Sort the dirnames to iterate over them in alphabetical order
dirnames.sort()
# Sort the filenames to iterate over them in alphabetical order
filenames.sort()
# Iterate over the files
for filename in filenames:
# Ignore hidden files
if filename.startswith('.'):
continue
# Only move one type of file
if not filename.endswith('.txt'):
continue
# Set the source path
src_path = Path(dirpath, filename)
# Only replace the first instance of the source folder's name
dst_dirpath = dirpath.replace(str(src_folder), dst_folder, 1)
dst_path = Path(dst_dirpath, filename)
# Check that the destination folder exists (create it if not)
os.makedirs(dst_dirpath, exist_ok=True)
# Move (which is actually a rename operation)
print(f'Moving "{src_path}" to "{dst_path}"')
os.rename(src_path, dst_path)
## Moving "Destination Folder/Example File.txt" to "Source Folder/Example File.txt"
## Moving "Destination Folder/Subfolder/Example File.txt" to "Source Folder/Subfolder/Example File.txt"
This is almost identical to the above, except the files are being copied (ie the originals are remaining where they are and duplicates are being created in the destination folders). The os
module can’t perform this operation, but the shutil
module can via the copy()
function:
# Source folder
src_folder = 'Source Folder'
# Destination folder
dst_folder = 'Destination Folder'
# Walk through the filesystem
for dirpath, dirnames, filenames in os.walk(src_folder):
# Sort the dirnames to iterate over them in alphabetical order
dirnames.sort()
# Sort the filenames to iterate over them in alphabetical order
filenames.sort()
# Iterate over the files
for filename in filenames:
# Ignore hidden files
if filename.startswith('.'):
continue
# Only move one type of file
if not filename.endswith('.txt'):
continue
# Set the source path
src_path = Path(dirpath, filename)
# Only replace the first instance of the source folder's name
dst_dirpath = dirpath.replace(str(src_folder), dst_folder, 1)
dst_path = Path(dst_dirpath, filename)
# Check that the destination folder exists (create it if not)
os.makedirs(dst_dirpath, exist_ok=True)
# Copy file
print(f'Copying "{src_path}" to "{dst_path}"')
shutil.copy(src_path, dst_path)
## Copying "Source Folder/Example File.txt" to "Destination Folder/Example File.txt"
## Copying "Source Folder/Subfolder/Example File.txt" to "Destination Folder/Subfolder/Example File.txt"
Again, to reset the folders to their original state so that this script can be re-run, I’ll delete the new copies of the files using the os.remove()
function:
# Folder which contains the files to be deleted
folder = 'Destination Folder'
# Walk through the filesystem
for dirpath, dirnames, filenames in os.walk(folder):
# Sort the dirnames to iterate over them in alphabetical order
dirnames.sort()
# Sort the filenames to iterate over them in alphabetical order
filenames.sort()
# Iterate over the files
for filename in filenames:
# Ignore hidden files
if filename.startswith('.'):
continue
# Only move one type of file
if not filename.endswith('.txt'):
continue
# Set the file path
path = Path(dirpath, filename)
print(f'Deleting "{path}"')
os.remove(path)
# Delete the directory if it is empty
try:
os.removedirs(dirpath)
except OSError:
pass
## Deleting "Destination Folder/Example File.txt"
## Deleting "Destination Folder/Subfolder/Example File.txt"
To finish, I’ll delete the example files and folders:
# Folder which contains the files to be deleted
folder = 'Source Folder'
# Walk through the filesystem
for dirpath, dirnames, filenames in os.walk(folder):
# Sort the dirnames to iterate over them in alphabetical order
dirnames.sort()
# Sort the filenames to iterate over them in alphabetical order
filenames.sort()
# Iterate over the files
for filename in filenames:
# Ignore hidden files
if filename.startswith('.'):
continue
# Only move one type of file
if not filename.endswith('.txt'):
continue
# Set the file path
path = Path(dirpath, filename)
print(f'Deleting "{path}"')
os.remove(path)
# Delete the directory if it is empty
try:
os.removedirs(dirpath)
except OSError:
pass
## Deleting "Source Folder/Example File.txt"
## Deleting "Source Folder/Subfolder/Example File.txt"