How to Copy Files and Rename them in Python [4 Ways]

avatar
Borislav Hadzhiev

Last updated: Aug 30, 2023
4 min

banner

# Table of Contents

  1. How to Copy Files and Rename them in Python
  2. Using the current timestamp to make the destination filename unique
  3. Copying all files from a directory to another directory and renaming them

# How to Copy Files and Rename them in Python

To copy files and rename them in Python:

  1. Import the copy() method from the shutil module.
  2. Pass the source path and the destination path to the shutil.copy() method.
  3. The method will copy the file to the new location with the updated name.
main.py
from shutil import copy src_path = 'example.txt' destination_path = 'example-new.txt' copy(src_path, destination_path) print('File copied and renamed successfully!')

copy and rename file in python

The code sample assumes that you have an example.txt file located int he same directory as your Python script.

example.txt
bobby hadz com

Running the script produces an example-new.txt file with the same contents.

example-new.txt
bobby hadz com

produced example txt file

You can also pass absolute paths to the shutil.copy() method.

The destination path can also be a directory.

The shutil.copy method copies the src file to the specified destination.

If the destination path points to a file that already exists, it will be replaced.

The copy() method copies the file data and the file's permission mode, however, the method doesn't copy the file creation and modification times.

If you want to preserve all file metadata from the original, use the shutil.copy2 method.

main.py
from shutil import copy2 src_path = 'example.txt' destination_path = 'example-new.txt' copy2(src_path, destination_path) print('File copied and renamed successfully!')

using shutil copy2 method

The copy2() method is identical to copy(), however, it also attempts to preserve file metadata.

# Using the current timestamp to make the destination filename unique

When using shutil.copy(), if the destination path points to a file that already exists, it will be replaced.

However, in some cases, you might need to produce unique destination filenames.

You can use the current timestamp to achieve this.

main.py
from datetime import datetime from shutil import copy2 timestamp = str(datetime.now())[:19] timestamp = timestamp.replace(':', '_') print(timestamp) src_path = 'example.txt' destination_path = f'example-{timestamp}.txt' copy2(src_path, destination_path) print(f'File copied to {destination_path}')

using current timestamp to make the destination filename unique

The code sample assumes that you have an example.txt file in the same directory as your Python script.

example.txt
bobby hadz com

Running the code sample copies the example.txt file to a destination that contains the current timestamp, e.g. example-2023-08-30 12_31_06.txt.

file copied to new destination with timestamp

We used the datetime.now method to get the current local date and time.

main.py
from datetime import datetime # ๐Ÿ‘‡๏ธ 2023-08-30 12:34:38.681721 print(datetime.now())

We used string slicing to exclude the milliseconds.

main.py
from datetime import datetime # ๐Ÿ‘‡๏ธ 2023-08-30 12:35:20 print(str(datetime.now())[:19])

The last step is to use the str.replace method to replace the colons with underscores.

main.py
from datetime import datetime # ๐Ÿ‘‡๏ธ 2023-08-30 12_36_02 print(str(datetime.now())[:19].replace(':', '_'))

Unless you rerun the command multiple times concurrently, the destination filename will be unique.

Alternatively, you can use the time() method from the time module to get the current time in seconds since the Epoch.

main.py
from time import time from shutil import copy2 timestamp = time() timestamp = str(timestamp).replace('.', '_') print(timestamp) # 1693388353_6106539 src_path = 'example.txt' destination_path = f'example-{timestamp}.txt' copy2(src_path, destination_path) print(f'File copied to {destination_path}')

Running the code sample produces the following output.

shell
1693388421_4974587 File copied to example-1693388421_4974587.txt

using time since epoch for unique file names

# Copying all files from a directory to another directory and renaming them

If you need to copy all files from a directory to another directory and rename them, use the following code sample.

main.py
import os from shutil import copy2 from pathlib import Path def copy_and_rename(src, dest): Path(destination).mkdir(parents=True, exist_ok=True) for item in os.listdir(src): current_path = os.path.join(src, item) if os.path.isdir(current_path): copy_and_rename(current_path, dest) elif current_path.endswith(".txt"): file_name, extension = item.rsplit('.', maxsplit=1) print(file_name) print(extension) updated_filename = file_name + '-new' + '.' + extension copy2( current_path, os.path.join( destination, updated_filename ) ) src_path = 'my-directory' destination = 'new-directory' copy_and_rename(src_path, destination)

The code sample assumes that you have the following folder structure.

shell
my-project/ โ””โ”€โ”€ main.py โ””โ”€โ”€ my-directory โ””โ”€โ”€ example-1.txt โ””โ”€โ”€ example-2.txt โ””โ”€โ”€ example.txt

Running the code sample produces a new-directory folder that has the following structure.

shell
new-directory/ โ””โ”€โ”€ example-1-new.txt โ””โ”€โ”€ example-2-new.txt โ””โ”€โ”€ example-new.txt

The copy_and_rename function takes source and destination directories, copies the files from the source directory to the destination directory and renames them.

The first line of the function creates the destination directory if it doesn't already exist.

main.py
Path(destination).mkdir(parents=True, exist_ok=True)

We used a for loop to iterate over the files and directories of the source directory.

main.py
for item in os.listdir(src): current_path = os.path.join(src, item)

We used an if statement to check if each item is a directory path.

main.py
if os.path.isdir(current_path): copy_and_rename(current_path, dest)

If the path is a directory, we call the copy_and_rename() function recursively.

The elif statement checks if the current item is a text file (ends with .txt).

main.py
elif current_path.endswith(".txt"): Path(destination).mkdir(parents=True, exist_ok=True) file_name, extension = item.rsplit('.', maxsplit=1) print(file_name) print(extension) updated_filename = file_name + '-new' + '.' + extension copy2( current_path, os.path.join( destination, updated_filename ) )

If the file is a text file, we rename it by adding the "-new" substring at the end and copy it using the shutil.copy2() method.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev