Chrisy
Chrisy

Reputation: 11

Python: simple batch rename files in windows folder

Trying to create a simple code, to batch rename a folder in windows.

Musts:

Is this possible?

I did test versions, combination of the little knowledge I have, but it gets me confused.

my code so far:

import os
import sys


folder_path = os.listdir(raw_input("Insert folder path: "))
print "Files in folder: %s" % folder_path

# a split tool
def mysplit(s):
    head = s.rstrip('0123456789')
    tail = s[len(head):]
    return head, tail

# a function to make a new name with needed 0000
def new_filename(filename):
    file_name_part, ext = os.path.splitext(filename) #  file01 and .ext

    original_name, number = mysplit(file_name_part) # 01 and file
    add_zero = number.rjust(4, "0") # add 0001

new_name = original_name + add_zero + ext

print new_name
    # new_name  comes like this ['file0001.txt'] but seperate, not in a list? Why?



for current_file_n in folder_path:
    new = new_filename(current_file_n)
    print list([new]) # trying to make the str into a list....


re_name = os.renames(current_file_n, new)
print re_name
print "Renamed files: %s" % folder_path

The desired outcome is the same as the beginning list, but collated with zeros,like this: ['file0001.txt', 'file0002.txt', 'file0003.txt'......'file0015.txt']

I've got errors like windows error: can't find file, and another error; can't connect str and list?

I need an explanation of what I'm doing wrong as simple as possible, or is there another method that I can use that will give me the desired outcome?

Upvotes: 0

Views: 937

Answers (2)

Håken Lid
Håken Lid

Reputation: 23064

Your code can be simplified a lot by using regular expression substitution. re.sub() can take a replacement function. In this case adding leading zeroes to the first number found in the filename.

import os, re

def renumber_files(directory, zeroes=4):
    os.chdir(directory)
    for filename in os.listdir(directory):
        new_name = re.sub(r'\d+', lambda m: m.group().zfill(zeroes), filename, count=1)
        os.rename(filename, new_name)


renumber_files(raw_input("Insert folder path: "))

This works because re.sub() can take a callable as the replacement argument.

Signature: re.sub(pattern, repl, string, count=0, flags=0) 

Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement repl. repl can be either a string or a callable; if a string, backslash escapes in it are processed. If it is a callable, it's passed the match object and must return a replacement string to be used.

In the lambda m.group() returns a string matching the pattern \d+. For instance "1", "564645" or "005".

The next step, str.zfill(4), turns those into "0001", "564645", or "0005".

Upvotes: 1

schafle
schafle

Reputation: 613

As martineau said your indentation is messed up.

Here's the working code:

import os
import sys

# a split tool
def mysplit(s):
    head = s.rstrip('0123456789')
    tail = s[len(head):]
    return head, tail

# a function to make a new name with needed 0000
def new_filename(filename):
    file_name_part, ext = os.path.splitext(filename) #  file01 and .ext

    original_name, number = mysplit(file_name_part) # 01 and file
    add_zero = number.rjust(4, "0") # add 0001

    new_name = original_name + add_zero + ext

    return new_name
    # new_name  comes like this ['file0001.txt'] but seperate, not in a list? Why?

if __name__ == '__main__':
     folder_path = os.listdir(raw_input("Insert folder path: "))
     print "Files in folder: %s" % folder_path
     renamed_files = [] 
     for current_file_n in folder_path:
          new = new_filename(current_file_n)
          renamed_files.append(new) # Add renamed file's name to a list
          try:
               os.renames(current_file_n, new) #It doesn't return anything
               print new
          except:
               print "Unexpected error while renaming %s:%s"%(new, sys.exc_info()[0])
     print "Renamed files: %s" % renamed_files

Hope this helps

Upvotes: 1

Related Questions