简体   繁体   中英

How to copy and rename all files in a directory using Python?

I am trying to copy all jpeg files from a directory (with multiple subdirectories) to a single directory. There are multiple files with the same name, so I am trying to rename the files using the name of the parent directory. For example: c:\\images\\tiger\\image_00001.jpg will be moved to a new folder and renamed to c:\\images\\allimages\\tiger_image_00001.jpg. I tried the code below, but nothing happens. The folder gets created, but the files do not move. This is what I have so far:

import os
path = 'source/'
os.mkdir('source/allimages/')
extensions = ['.jpeg']
for folder, _, filenames in os.walk(path):
    for filename in filenames:
        if folder == path or folder == os.path.join(path, 'allimages'):
            continue
        folder = folder.strip(path)
        extension = os.path.splitext(os.path.splitext(filename)[0])[-1].lower()
        if extension in extensions:
            infilename = os.path.join(path, folder, filename)
            newname = os.path.join(path, 'all_files', "{}-{}".format(folder.strip('./')))
            os.rename(infilename, newname)

I would recommend having a function dedicated to resolving a unique filename. A while loop should do the trick. This should work.

import os
import shutil

def resolve_path(filename, destination_dir):
    dest = os.path.join(destination_dir, filename)
    *base_parts, extension = filename.split('.')
    base_name = '.'.join(base_parts)
    duplicate_num = 1
    while os.path.exists(dest):
        new_base = base_name + str(duplicate_num).zfill(5)
        new_filename = "{}.{}".format(new_base, extension)
        dest = os.path.join(destination_dir, new_filename)
        duplicate_num += 1
    return dest

That is such that the following is the result....

>>> with open('/path/to/file.extension', 'w') as f:
>>>     pass # just create the file
>>> resolve_path('file.extension', '/path/to/')
'/path/to/file00001.extension'        

Then put it together with traversing the source...

def consolidate(source, destination, extension='.jpg'):
    if not os.path.exists(destination):
        os.makedirs(destination)
    for root, dirs, files in os.walk(source):
        for f in files:
            if f.lower().endswith(extension):
                source_path = os.path.join(root, f)
                destination_path = resolve_path(f, destination)
                shutil.copyfile(source_path, destination_path)

You're calling splitext on its own output, which doesn't get what you want:

In [4]: os.path.splitext(os.path.splitext('foo.bar')[0])[-1]
Out[4]: ''

You just want extension = os.path.splitext(filename)[-1].lower() , or if you don't want the dot, then extension = os.path.splitext(filename)[-1].lower()[1:] .

(Edited) more seriously, there's a problem with folder.strip(path) : this will remove all characters in path from folder. For instance 'source/rescue'.strip('source/') == '' . What you want is folder.replace(path, '') .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM