2

I've been trying to get this to work, but I feel like I'm missing something. There is a large collection of images in a folder that I need to rename just part of the filename. For example, I'm trying to rename the "RJ_200", "RJ_600", and "RJ_60"1 all to the same "RJ_500", while keeping the rest of the filename intact.

Image01.Food.RJ_200.jpg
Image02.Food.RJ_200.jpg
Image03.Basket.RJ_600.jpg
Image04.Basket.RJ_600.jpg
Image05.Cup.RJ_601.jpg
Image06.Cup.RJ_602.jpg

This is what I have so far, but it keeps just giving me the "else" instead of actually renaming any of them:

import os
import fnmatch
import sys

user_profile = os.environ['USERPROFILE']
dir = user_profile + "\Desktop" + "\Working"

print (os.listdir(dir))

for images in dir:
    if images.endswith("RJ_***.jpg"):
        os.rename("RJ_***.jpg", "RJ_500.jpg")
    else:
        print ("Arg!")
martineau
  • 119,623
  • 25
  • 170
  • 301
KnightIK
  • 31
  • 4
  • *** doesn't work in this case. But I don't know what to write instead of those – sertsedat Jun 15 '15 at 15:47
  • Literal backslashes in strings need to be doubled, or have an `r` raw string prefix added. i.e. `user_profile + "\\Desktop\\Working"` or `user_profile + r"\Desktop\Working"`. – martineau Jun 22 '15 at 17:33

2 Answers2

3

The Python string method endswith does not do pattern-matching with *, so you're looking for filenames which explicitly include the asterisk character and not finding any. Try using regular expressions to match your filenames and then building your target filename explicitly:

import os
import re
patt = r'RJ_\d\d\d'

user_profile = os.environ['USERPROFILE']
path = os.path.join(user_profile, "Desktop", "Working")
image_files = os.listdir(path)

for filename in image_files:
    flds = filename.split('.')
    try:
        frag = flds[2]
    except IndexError:
        continue
    if re.match(patt, flds[2]):
        from_name = os.path.join(path, filename)
        to_name = '.'.join([flds[0], flds[1], 'RJ_500', 'jpg'])
        os.rename(from_name, os.path.join(path, to_name))

Note that you need to do your matching with the file's basename and join on the rest of the path later.

xnx
  • 24,509
  • 11
  • 70
  • 109
  • I tried it, but it keeps giving me an error at the "re.match(patt, flds[2]): It says "list index out of range" – KnightIK Jun 15 '15 at 17:21
  • Sorry, I'm still trying to learn. I'm guessing it's because I need to create a counter for it? Otherwise it just keeps iterating over and over again in the same folder? – KnightIK Jun 15 '15 at 17:24
  • Evidently some of the files in your directory are not of the form you want to change: you can skip these ones using the code in the edit I've made. – xnx Jun 15 '15 at 17:24
  • Thanks a lot for the help! It worked like I wanted and sent me down a much more complicated path. Which is good, I think. lol – KnightIK Jun 22 '15 at 14:58
  • Literal backslashes in strings need to be doubled, or have an `r` raw string prefix added. So in addition doing that for the `path` variable, in your answer it would need to be done to the literal assigned to `patt`. – martineau Jun 22 '15 at 17:34
  • That's a fair comment (although I don't think \d, \W and \D actually correspond to valid escape sequences do they?) -- I've used `os.path.join` as I should have and a raw string for the regex pattern. – xnx Jun 22 '15 at 17:49
1

You don't need to use .endswith. You can split the image file name up using .split and check the results. Since there are several suffix strings involved, I've put them all into a set for fast membership testing.

import os
import re
import sys

suffixes = {"RJ_200", "RJ_600", "RJ_601"}
new_suffix = "RJ_500"

user_profile = os.environ["USERPROFILE"]
dir = os.path.join(user_profile, "Desktop", "Working")

for image_name in os.listdir(dir):
    pieces = image_name.split(".")
    if pieces[2] in suffixes:
        from_path = os.path.join(dir, image_name)
        new_name = ".".join([pieces[0], pieces[1], new_suffix, pieces[3]])
        to_path = os.path.join(dir, new_name)
        print("renaming {} to {}".format(from_path, to_path))
        os.rename(from_path, to_path)
martineau
  • 119,623
  • 25
  • 170
  • 301