• Martin Thoma
  • Home
  • Categories
  • Tags
  • Archives
  • Support me

Rename Script

Once in a while I have to bulk rename files. For example, when I have holiday photos. The following script helps me to do so:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Batch-Rename files in a folder according to some rules."""

import os
import math
from PIL import Image


def get_date_taken(path):
    """Get the date when the image was taken."""
    print(path)
    im = Image.open(path)
    if im is not None or im._getexif() is None:
        return im._getexif()[36867]
    else:
        print("Could not find date in EXIF data for '%s'" % path)
        return os.stat(path).st_ctime


def rename(rename, starts=None, ends=None, test=False):
    """
    Rename all files in a nice way.

    Only files which end with `ends` and start with `starts` are renamed to
    `rename-[Number]`.
    """
    files = [f for f in os.listdir(".") if os.path.isfile(f) and not f.endswith(".py")]
    # Sort files by last modification / creation
    files.sort(key=lambda x: os.stat(x).st_ctime)  # st_ctime or st_mtime
    files.sort(key=lambda x: get_date_taken(x))
    if starts is not None:
        files = [f for f in files if f.lower().startswith(starts.lower())]
    if ends is not None:
        files = [f for f in files if f.lower().endswith(ends.lower())]
    for i, f in enumerate(files, start=1):
        filename, ext = os.path.splitext(f)
        ext = ext.lower()
        digits = int(math.log10(len(files))) + 1
        number = str(i).zfill(digits)
        new_name = "%s-%s%s" % (rename, number, ext)
        if test:
            print("{0:<40}-> {1:<20}".format(f, new_name))
        else:
            os.rename(f, new_name)


def get_parser():
    """Parser for rename script."""
    from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter

    parser = ArgumentParser(
        description=__doc__, formatter_class=ArgumentDefaultsHelpFormatter
    )
    parser.add_argument(
        "-n", "--name", dest="name", help="new name", required=True, metavar="NAME"
    )
    parser.add_argument(
        "-s",
        "--starts",
        dest="starts",
        help="Get files which start with this string",
        default=None,
        metavar="STARTS",
    )
    parser.add_argument(
        "-e",
        "--ends",
        dest="ends",
        help="Get files which end with this string",
        default=None,
        metavar="ENDS",
    )
    parser.add_argument(
        "-t",
        "--test",
        action="store_true",
        dest="test",
        default=False,
        help="don't change anything, just show what would be " "done",
    )
    return parser


if __name__ == "__main__":
    args = get_parser().parse_args()
    rename(args.name, starts=args.starts, ends=args.ends, test=args.test)

Published

Sep 16, 2015
by Martin Thoma

Category

Cyberculture

Tags

  • File 2
  • Python 141
  • Rename 1

Contact

  • Martin Thoma - A blog about Code, the Web and Cyberculture
  • E-mail subscription
  • RSS-Feed
  • Privacy/Datenschutzerklärung
  • Impressum
  • Powered by Pelican. Theme: Elegant by Talha Mansoor