37|PYTHON – Move Those Files

BYU Student Author: @klayton
Reviewers: @Parker_Sherwood @Mike_Paulsin, @Jonathan_Weston
Estimated Time to Solve: 20 Minutes

We provide the solution to this challenge using:

  • Python

Need a program? Click here.

You are a new employee at a local accounting firm, and in your entry level position you are often tasked with the more menial tasks. One of these tasks is moving all the invoices you send to clients from the “Invoices to Send” folder into their specific client folders. Manually moving all these files can be very time consuming, and you want to impress your new boss by finding a way to perform this task quickly and accurately.

The following packages might help in this challenge, glob, shutil, and re (regex), but feel free to use any you like!

Create a function in python that has the following specifications:

  • Name your function “move_files”
  • It must take input for the beginning and destination folders’ filepaths.
    • The script should check to make sure the string for the filepath ends with “\” and either add the “\” if it isn’t there or prompt the user to try again and add the slash themselves.
  • Use glob to put all the files into a list.
  • The file names should stay the same in the transfer.
  • The attached zip folder contains the invoices as well as the client folders. The invoice files should be moved into the folder “invoices” in their respective client folder.

Data Files

Suggestions and Hints
  • In python “\” is a special character that changes the meaning of the following character, so when checking for that character at the end of a string use “\” instead of “\”. The latter will ignore the end quotation mark and cause errors.
  • Use “Print()” often to check what is happening in your code.
  • The glob module in Python is used to retrieve file paths that match a specified pattern, allowing users to easily search for files and directories with specific names or extensions.
  • The shutil module in Python provides a higher-level interface for file operations, including copying, moving, renaming, and deleting files and directories, making it easier for users to manage file operations on their system.


import glob
import shutil
import re

def move_files(src_folder, dest_folder):
    # Ensure the filepaths end with a backslash
    if not src_folder.endswith("\\"):
        src_folder += "\\"

    if not dest_folder.endswith("\\"):
        dest_folder += "\\"

    # Use glob to put all the files into a list
    file_list = glob.glob(src_folder + "*.*")

    # Iterate through the files and move them to the respective client folders
    for file in file_list:
        # Extract the client name from the file name using regex
        client_name = re.search(r'client\d+', file).group()

        # Define the destination path for the invoice
        dest_path = dest_folder + client_name + "\\invoices\\"

        # Move the file to the destination path
        shutil.move(file, dest_path)

    print("Files moved successfully.")

# Example usage
src_folder = "path\\to\\InvoicesToSend"
dest_folder = "path\\to\\ClientFolders"

move_files(src_folder, dest_folder)
1 Like

This was a great challenge! I ended up using an input statement get the file path for the folder to get past most of the double backslash issues.

Here’s my solution:

from glob import glob
import shutil
import os

#Create a directory for the Challenge PDF Mover folder and a directory for wherever your python notebook operates.
#Include an os.makedirs statement in case you create filepaths that do not exist.
folder_directory = input('Please enter the file path for the Challenge PDF Merger Folder.')
if folder_directory[-2] != '\\':
    folder_directory = folder_directory + '\\'
directory = os.getcwd()+'\\'
os.makedirs(os.path.dirname(directory), exist_ok=True)

#Create a list of the invoices within the Challenge folder
invoices = glob(folder_directory+'*.pdf')

#Loop through each client folder and create a directory
for invoice in invoices:
    invoice = invoice.split('\\')[-1]
    client = invoice.split('#')[0]
    client_invoice_directory = folder_directory+'\\Client Folders\\'+client+'\\Invoices\\'

    #Move the file from the challenge folder into the client's folder.
1 Like
import os
import shutil
import glob

def move_files(src_folder, dst_folder):
    # folders must end with \
    # prompt user to ender correct syntax
    if not src_folder.endswith('\\'):
        print(f"The source folder path '{src_folder}' is missing a trailing backslash. Please add it and try again.")
    if not dst_folder.endswith('\\'):
        print(f"The destination folder path '{dst_folder}' is missing a trailing backslash. Please add it and try again.")

    # Get a list of all files in first folder
    lFile = glob.glob(os.path.join(src_folder, '*'))

    # Move each file to the invoices subfolder of its client folder in dst_folder
    for oFile in lFile:
        #get client name
        client_name = os.path.splitext(os.path.basename(oFile))[0]

        # make new folder for destination
        client_folder = os.path.join(dst_folder, client_name)
        invoices_folder = os.path.join(client_folder, 'invoices')

        # Create the client and invoices folders if they don't exist
        os.makedirs(invoices_folder, exist_ok=True)

        # Move invoices folder
        shutil.move(oFile, invoices_folder)
        #print concatenated statement
        print(f"Moved file '{oFile}' to '{invoices_folder}'")
1 Like

Great challenge! It was my first time using glob. I really like how easy it is to find all the pdfs in the file. My solution was similar to Jonathan’s and Hunters.

I see how this could be really beneficial in the workplace to help automate mundane tasks. Looking forward to using this in the future, hopefully I have an opportunity to use this during my internship.

1 Like

Interesting challenge highlight a very practical use of the Glob module!

I ended up using Regex grouping with re.findall() which was a fun challenge. I also used os.path.exists to make sure the starting and ending filepaths were valid directories before entering the function.

# Import relevant files
from glob import glob
import os
import re
import shutil

def move_files(start_path, dest_path):
    # Get all files in a list
    files = glob(start_path + '*.pdf')
    for file in files:
        # parse out client name using Regex grouping
        client_name = re.findall(r'.*(\d{6})#\d+[a-zA-Z]?.pdf', file)
        # Move into relevant folder
        shutil.move(file, dest_path+client_name[0]+'\\Invoices\\')
    print('Files have been moved!')

while True:
    start_path = input('Please enter source folder: ')
    dest_path = input('Please enter destination folder: ')
    if start_path[-1] != '\\':
        start_path = start_path + '\\'
    if dest_path[-1] != '\\':
        dest_path = dest_path + '\\'
    if os.path.exists(start_path) == True and os.path.exists(dest_path) == True:
        # exists loop only when filepaths are valid
        print('Filepath is invalid. Please try again.\n')

move_files(start_path, dest_path)
1 Like

Pretty cool challenge!! After I created my solution, I went back and saw a good number of people had imported regular expressions to get the file names, but I did everything through text parsing. I also didn’t check to see if the directory existed like some others did, but I guess I assumed the destination path was clean :man_shrugging: Here’s my solution! My solution returns a dictionary of where the file was moved from connected to where it was stored.

from glob import glob as g
import shutil

def move_files():
append to filepaths
oldPath= input(“please enter the file path to you’re stored Invoices.”)
newPath=input(“Please enter the file path where you have all your client folders.”)
while True:
if oldPath[-1]!=‘\’:
oldPath = oldPath+‘\’
if newPath[-1]!=‘\’:
newPath = newPath+‘\’
#cylce through glob list
if len(g(oldPath+‘.pdf’))<1:
oldPath = input(“The source file Path doesn’t contain any PDFs. Please add the invoices or correct your file source”)
for file in g(oldPath+'
client_name = file.split(‘\’)[-1].split(‘#’)[0]
destination = newPath + client_name+‘\Invoices\’

return myDict