0

I would like to rename the following files from

l4_0_0.m4a
l4_0_1.m4a
l4_0_2.m4a
l5_0_0.m4a
l5_0_1.m4a
l5_0_2.m4a
l6_0_0.m4a
.
.
.
l11_0_2.m4a

To the following names

l5_0_0.m4a
l5_0_1.m4a
l5_0_2.m4a
l6_0_0.m4a
l6_0_1.m4a
l6_0_2.m4a
l7_0_0.m4a
.
.
.
l12_0_2.m4a

I am developing an application that used to have 12 levels, I had to add a level before level 5 (l4__) therefore, I have to rename all the levels after level five. level 5 (l4__) will be level 6(l5__)

I am new to python and regular expressions. Any help will be appreciated it. Thanks

4
  • Hello Suha, what did you try ? Commented Dec 2, 2018 at 2:36
  • Hi @Zulu, I tried to manipulate the code in the link below but it did not work since I have two "_" in my file name, also in the like the file first name first part is constant which is not the case for my files: stackoverflow.com/questions/17748228/… Commented Dec 2, 2018 at 9:00
  • Are you willing to learn python regular expressions or are you expecting somebody else to help you out with a solution? Commented Dec 2, 2018 at 9:16
  • I want to learn it but this question although is trivial for @greybeard is not for me Commented Dec 2, 2018 at 9:38

2 Answers 2

2

Using a regular expression with symbolic group names will allow you to easily access the parts of the file name you wish to manipulate. I used a class as I thought you may want to add additional functionality to the renaming process such as sub levels or the lowest level.

#!/usr/bin/env python3

import re
import os


class NamedFile(object):
    file_mask = re.compile(r"(?P<PREFIX>l)(?P<LEVEL>\d+)_(?P<SUBLEVEL>\d+)_(?P<LOWLEVEL>\d+)\.(?P<EXTENSION>m4a)")
    file_format = "{PREFIX}{LEVEL}_{SUBLEVEL}_{LOWLEVEL}.{EXTENSION}".format

    @classmethod
    def files(cls, path):
        for f in sorted(os.listdir(path)):
            groups = cls.file_mask.match(f)
            if groups is not None:
                yield (path, f, groups.groupdict())

    @classmethod
    def new_name(cls, groups, increment):
        level = int(groups["LEVEL"]) + 1
        groups["LEVEL"] = level
        return cls.file_format(**groups)

    @classmethod
    def rename(cls, path, increment):
        for path, f, file_parts in NamedFile.files(path):
            new_filename = cls.new_name(file_parts, increment)
            abs_new = os.path.join(path, new_filename)
            abs_old = os.path.join(path, f)
            os.rename(abs_old, abs_new)


if __name__ == "__main__":
    print("===Original file names===")
    for path, f, file_parts in NamedFile.files("."):
        print(f)

    NamedFile.rename(".", 1)

    print("===New file names===")
    for path, f, file_parts in NamedFile.files("."):
        print(f)
Sign up to request clarification or add additional context in comments.

2 Comments

Did you mean import os instead of import os.path?
Your answer is complete and wonderful.... a few minutes ago I needed to change the low level...thanks a lot @Kristian
1

The following should do it. Run it in the directory those files are in, and it will produce the new files in a directory called out.

from os import listdir, makedirs
from os.path import exists, isfile, join
import re
import shutil

output_dir = 'out'

files = [f for f in listdir('.') if isfile(join('.', f)) and f.endswith('.m4a')]

if not exists(output_dir):
    makedirs(output_dir)

for f in files:
    level, suffix = re.match(r'^l([0-9]+)(_.+)', f).groups()
    shutil.copyfile(f, join(output_dir, 'l%d%s' % (int(level) + 1, suffix)))

Result:

$ ls
l4_0_0.m4a  l4_0_1.m4a  l4_0_2.m4a  l5_0_0.m4a  l5_0_1.m4a  l5_0_2.m4a  rename.py

$ python rename.py
$ ls out
l5_0_0.m4a  l5_0_1.m4a  l5_0_2.m4a  l6_0_0.m4a  l6_0_1.m4a  l6_0_2.m4a

3 Comments

Doesn't os have a rename() function?
@Tomothy32 Yes, I chose shutil.copyfile to leave the original files as is, just in case.
That is helpful thanks...but what if the files are in subfolders.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.