0

I am trying to use python to rename over 1000 files in a windows directory that have this naming convention:

The.Woman.In.Black.2012.720p.BluRay.x264

The desired naming convention is: The Woman In Black {2012}

The only important things I need from the original name are the title and date....

I have tried using different variations of string manipulation and I am not getting anywhere. I need help getting started.

I understand I should use the os module to rename files, but what procedure should I try and use to do this task?

Any help would be greatly appreciated. Thanks.

inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241
PythonFor Days
  • 201
  • 2
  • 11

4 Answers4

3
filename = 'The.Woman.In.Black.2012.720p.BluRay.x264'

# using regular expressions
import re
title, year = re.match('(.*?)\.(\d{4})\.720p\.BluRay\.x264', filename).groups()

# simpler regular expression, matching any format specifiers
title, year = re.match('(.+)\.(\d{4})\.', filename).groups()

# using simple string manipulation if the suffix is always the same
title, year = filename[:-22], filename[-21:-17]

# normalize title
title = title.replace('.', ' ')

# build new filename
print('%s {%s}' % (title, year)) # The Woman In Black {2012}

To rename files, use os.rename; to iterate through a directory, use glob.glob or os.walk.

poke
  • 369,085
  • 72
  • 557
  • 602
1

It looks like the general format of your titles is:

name.name.name.name.name.date.resolution.format.codec

in which case I would do this (not tested):

import os

TARGET_DIR = r'/path/to/movies/'

for old_title in os.listdir(TARGET_DIR + '*'):
    words = old_title.split('.')
    date = words[-4]
    name = ' '.join(words[:-4])
    new_title = '%s {%s}' % (name, date)
    old_title = os.path.join(TARGET_DIR, old_title)
    new_title = os.path.join(TARGET_DIR, new_title)
    os.rename(old_title, new_title)
Ethan Furman
  • 63,992
  • 20
  • 159
  • 237
0

If the original naming convention is consistent, you could split the original filename string on the '.' character, and then look for a valid year, add the braces, and join it with all the preceding tokens to form the new name.

See this question for how to rename a file using python.

Community
  • 1
  • 1
WildCrustacean
  • 5,896
  • 2
  • 31
  • 42
0
def change_filename(name):
    filename = name.split('.')
    wordlist = filename[:-4]
    extension = '.' + filename[-1]
    wordlist[-1] = '{' + wordlist[-1] + '}'
    os.rename(name, ' '.join(wordlist) + extension)

This function should do exactly what you want, you just need to feed it the names.

Note: you probably want to add a file extension on to the filename, otherwise it might go wonky and everything.

If you run this on the same file more than once, you'll get a file overloaded with braces, and you don't want that, so here's a reversal function:

def filename_cleanup(name):
    filename = name.replace('{', '').replace('}', '')
    wordlist = filename.split(' ')
    extension = '.' + wordlist.pop()
    wordlist[-1] = '{' + wordlist[-1] + '}'
    os.rename(name, ' '.join(wordlist) + extension)

That should give you the proper filename again.

Volatility
  • 31,232
  • 10
  • 80
  • 89
  • One more question... If I re-run the script multiple times, it keeps adding a layer of '{}' around the file name. For example... after testing and running the script many times, The files now are like so: {{{{{{{{Vacancy {2007} {mp4}}}}}}}}}. How can I prevent this behavior? – PythonFor Days Jan 02 '13 at 06:08
  • If you run it on the same file over and over again, it'll stuff up. For example, if we feed `'The Woman In Black {2012}.mp4'` into the function, we split on every `'.'`, and `filename` becomes `['The Woman In Black {2012}', 'mp4'], then it puts braces around `'mp4'` and gets rid of the file extension. If you run it again there is no `'.'` to split the file into and so the braces will go around the whole file name. – Volatility Jan 02 '13 at 06:15
  • In this case, I am running it on the entire directory by putting the .py in the same directory and executing it. I've botched all the names now, how would you recover from here? – PythonFor Days Jan 02 '13 at 06:20
  • You'll probably have to get rid of all the braces, and then go from there. Do you need the code? – Volatility Jan 02 '13 at 06:41
  • I hate to admit it but... yea. – PythonFor Days Jan 02 '13 at 07:07
  • Thanks. I've been breaking down your code and playing with it in shell and have a pretty good idea of how it works now. Thanks for the help on this. I'm learning one step at a time. – PythonFor Days Jan 02 '13 at 07:29
  • This solution won’t work with [`2012 (2009)`](http://www.imdb.com/title/tt1190080/) though. – poke Jan 02 '13 at 12:59
  • @poke sorry for the misunderstanding, but anyway the solution should work now (assuming the filename input has an extension on it) – Volatility Jan 02 '13 at 20:47
  • If I was going to os.walk the directory and put all the files into a list how would I feed it to this function? – PythonFor Days Jan 03 '13 at 04:20
  • I'm not entirely familiar with `os.walk` since I haven't used it, but the docs say that it returns the file names as the last element of a three-tuple. I'm assuming it's gonna be a list of some sort, so all you need to do is extract that list (maybe by `os.walk(directory)[-1]`) and feed every element to the function. – Volatility Jan 03 '13 at 05:06
  • I'm not sure I know what you mean. What I am trying to do is run the script and have it use the functions you supplied on all the files in a directory. – PythonFor Days Jan 03 '13 at 05:52
  • Do you know what `os.walk` does and what it returns? – Volatility Jan 03 '13 at 05:55
  • With `for data in os.walk("C:\Users\SyFYChryme\Videos\Movies"):` `movies.append(data)` I am able to get all the titles in a list. I just don;t know how to take them, one by one and run them through the function to be renamed. – PythonFor Days Jan 03 '13 at 12:01
  • oh, ok then, all you need to do is just in the for loop, do `change_filename(data)` and that should work (or of course the other function if you wanted to) – Volatility Jan 03 '13 at 12:09