Python Forum
Improving code to autorename if filename exists - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Improving code to autorename if filename exists (/thread-21267.html)



Improving code to autorename if filename exists - Den0st - Sep-21-2019

Hi all, I have a part of my code that I would like to give a little upgrade.
import os
import shutil

dest = '/path/to/dest_folder'
src = '/path/to/src_folder'

for root, subdirs, files in os.walk(src):
    for file in files:
        path = os.path.join(root, file)
        shutil.move(path, dest)
This code replaces files from a folder and its subfolders to one destination-folder. The problem here is: If there are 2 files with thesame filename I get an error:
Quote:shutil.Error: Destination path '/path/to/dest_folder/filename' already exists

I'd like to change this code so it automaticly renames the file if it already exists in the destination-folder because thesame filename doesn't mean it has thesame content so I don't want to overwrite files in the destination-folder.

I've been thinking about using a timestamp but I'm not sure If and how to do it. Any tips? Ideas?

Thanks :)


RE: Improving code to autorename if filename exists - wavic - Sep-22-2019

Hello!
Just catch the error.
for root, subdirs, files in os.walk(src):
    for file in files:
        path = os.path.join(root, file)
        try:
            shutil.move(path, dest)
        except shutil.Error:
            #rename the file



RE: Improving code to autorename if filename exists - ndc85430 - Sep-22-2019

You can look at the datetime module if you want to do things with, well, dates and times.


RE: Improving code to autorename if filename exists - Gribouillis - Sep-22-2019

Browsers or other downloading programs often have the strategy to create filename-1.txt, filename-2.txt, ... if filename.txt already exists. Here is a way to generate them
import itertools as itt
import os
import re

def altnames(filename):
    """Generate a sequence of alternate names for a filename.
    
    The first name generated is filename itself.
    """
    yield filename
    stem, ext = os.path.splitext(filename)
    match = re.search(r'\-(\d+)$', stem)
    if match:
        n = int(match.group(1))
        s = stem[:match.start()]
    else:
        n = 0
        s = stem
    for i in itt.count(n+1):
        yield '{}-{}{}'.format(s, i, ext)
        
if __name__ == '__main__':
    for f in ['ham.py', 'spam-122.txt', 'eggs-11-13.pdf']:
        for n in itt.islice(altnames(f), 3):
            print(n)
Result:
Output:
ham.py ham-1.py ham-2.py spam-122.txt spam-123.txt spam-124.txt eggs-11-13.pdf eggs-11-14.pdf eggs-11-15.pdf



RE: Improving code to autorename if filename exists - Den0st - Sep-22-2019

(Sep-22-2019, 07:10 AM)wavic Wrote: Hello!
Just catch the error.
for root, subdirs, files in os.walk(src):
    for file in files:
        path = os.path.join(root, file)
        try:
            shutil.move(path, dest)
        except shutil.Error:
            #rename the file

Hi, thisone looks like it's the easiest solution. I did a lot of research on renaming the file but I didn't really figure it out yet (with my pretty basic knowledge). Do you have any suggestions about how I should rename the file?

(Sep-22-2019, 09:50 AM)Gribouillis Wrote: Browsers or other downloading programs often have the strategy to create filename-1.txt, filename-2.txt, ... if filename.txt already exists. Here is a way to generate them
import itertools as itt
import os
import re

def altnames(filename):
    """Generate a sequence of alternate names for a filename.
    
    The first name generated is filename itself.
    """
    yield filename
    stem, ext = os.path.splitext(filename)
    match = re.search(r'\-(\d+)$', stem)
    if match:
        n = int(match.group(1))
        s = stem[:match.start()]
    else:
        n = 0
        s = stem
    for i in itt.count(n+1):
        yield '{}-{}{}'.format(s, i, ext)
        
if __name__ == '__main__':
    for f in ['ham.py', 'spam-122.txt', 'eggs-11-13.pdf']:
        for n in itt.islice(altnames(f), 3):
            print(n)
Result:
Output:
ham.py ham-1.py ham-2.py spam-122.txt spam-123.txt spam-124.txt eggs-11-13.pdf eggs-11-14.pdf eggs-11-15.pdf

This looks really interesting but with my basic python-knowledge difficult to understand or to figure out how I should implement this in my own code. But thank you anyways! :)


RE: Improving code to autorename if filename exists - wavic - Sep-23-2019

If you have file 'file.txt' ou can rename it 'file(1).txt' for example - as browsers do. Or without the brackets if you like it more.