Rename multiple files in a directory in Python

PythonFile IoFile Rename

Python Problem Overview


I'm trying to rename some files in a directory using Python.

Say I have a file called CHEESE_CHEESE_TYPE.*** and want to remove CHEESE_ so my resulting filename would be CHEESE_TYPE

I'm trying to use the os.path.split but it's not working properly. I have also considered using string manipulations, but have not been successful with that either.

Python Solutions


Solution 1 - Python

Use os.rename(src, dst) to rename or move a file or a directory.

$ ls
cheese_cheese_type.bar  cheese_cheese_type.foo
$ python
>>> import os
>>> for filename in os.listdir("."):
...  if filename.startswith("cheese_"):
...    os.rename(filename, filename[7:])
... 
>>> 
$ ls
cheese_type.bar  cheese_type.foo

Solution 2 - Python

Here's a script based on your newest comment.

#!/usr/bin/env python
from os import rename, listdir

badprefix = "cheese_"
fnames = listdir('.')

for fname in fnames:
    if fname.startswith(badprefix*2):
        rename(fname, fname.replace(badprefix, '', 1))

Solution 3 - Python

The following code should work. It takes every filename in the current directory, if the filename contains the pattern CHEESE_CHEESE_ then it is renamed. If not nothing is done to the filename.

import os
for fileName in os.listdir("."):
	os.rename(fileName, fileName.replace("CHEESE_CHEESE_", "CHEESE_"))

Solution 4 - Python

Assuming you are already in the directory, and that the "first 8 characters" from your comment hold true always. (Although "CHEESE_" is 7 characters... ? If so, change the 8 below to 7)

from glob import glob
from os import rename
for fname in glob('*.prj'):
    rename(fname, fname[8:])

Solution 5 - Python

I have the same issue, where I want to replace the white space in any pdf file to a dash -. But the files were in multiple sub-directories. So, I had to use os.walk(). In your case for multiple sub-directories, it could be something like this:

import os
for dpath, dnames, fnames in os.walk('/path/to/directory'):
    for f in fnames:
        os.chdir(dpath)
        if f.startswith('cheese_'):
            os.rename(f, f.replace('cheese_', ''))

Solution 6 - Python

Try this:

import os
import shutil

for file in os.listdir(dirpath):
    newfile = os.path.join(dirpath, file.split("_",1)[1])
    shutil.move(os.path.join(dirpath,file),newfile)

I'm assuming you don't want to remove the file extension, but you can just do the same split with periods.

Solution 7 - Python

This sort of stuff is perfectly fitted for IPython, which has shell integration.

In [1] files = !ls
In [2] for f in files:
           newname = process_filename(f)
           mv $f $newname

Note: to store this in a script, use the .ipy extension, and prefix all shell commands with !.

See also: http://ipython.org/ipython-doc/stable/interactive/shell.html

Solution 8 - Python

Here is a more general solution:

This code can be used to remove any particular character or set of characters recursively from all filenames within a directory and replace them with any other character, set of characters or no character.

import os
 
paths = (os.path.join(root, filename)
        for root, _, filenames in os.walk('C:\FolderName')
        for filename in filenames)
 
for path in paths:
    # the '#' in the example below will be replaced by the '-' in the filenames in the directory
    newname = path.replace('#', '-')
    if newname != path:
        os.rename(path, newname)

Solution 9 - Python

It seems that your problem is more in determining the new file name rather than the rename itself (for which you could use the os.rename method).

It is not clear from your question what the pattern is that you want to be renaming. There is nothing wrong with string manipulation. A regular expression may be what you need here.

Solution 10 - Python

This command will remove the initial "CHEESE_" string from all the files in the current directory, using renamer:

$ renamer --find "/^CHEESE_/" *

Solution 11 - Python

import os import string def rename_files():

#List all files in the directory
file_list = os.listdir("/Users/tedfuller/Desktop/prank/")
print(file_list)

#Change current working directory and print out it's location
working_location = os.chdir("/Users/tedfuller/Desktop/prank/")
working_location = os.getcwd()
print(working_location)

#Rename all the files in that directory
for file_name in file_list:
    os.rename(file_name, file_name.translate(str.maketrans("","",string.digits)))

rename_files()

Solution 12 - Python

I was originally looking for some GUI which would allow renaming using regular expressions and which had a preview of the result before applying changes.

On Linux I have successfully used krename, on Windows Total Commander does renaming with regexes, but I found no decent free equivalent for OSX, so I ended up writing a python script which works recursively and by default only prints the new file names without making any changes. Add the '-w' switch to actually modify the file names.

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

import os
import fnmatch
import sys
import shutil
import re


def usage():
    print """
Usage:
        %s <work_dir> <search_regex> <replace_regex> [-w|--write]

        By default no changes are made, add '-w' or '--write' as last arg to actually rename files
        after you have previewed the result.
        """ % (os.path.basename(sys.argv[0]))


def rename_files(directory, search_pattern, replace_pattern, write_changes=False):

    pattern_old = re.compile(search_pattern)

    for path, dirs, files in os.walk(os.path.abspath(directory)):

        for filename in fnmatch.filter(files, "*.*"):

            if pattern_old.findall(filename):
                new_name = pattern_old.sub(replace_pattern, filename)

                filepath_old = os.path.join(path, filename)
                filepath_new = os.path.join(path, new_name)

                if not filepath_new:
                    print 'Replacement regex {} returns empty value! Skipping'.format(replace_pattern)
                    continue

                print new_name

                if write_changes:
                    shutil.move(filepath_old, filepath_new)
            else:
                print 'Name [{}] does not match search regex [{}]'.format(filename, search_pattern)

if __name__ == '__main__':
    if len(sys.argv) < 4:
        usage()
        sys.exit(-1)

    work_dir = sys.argv[1]
    search_regex = sys.argv[2]
    replace_regex = sys.argv[3]
    write_changes = (len(sys.argv) > 4) and sys.argv[4].lower() in ['--write', '-w']
    rename_files(work_dir, search_regex, replace_regex, write_changes)
Example use case

I want to flip parts of a file name in the following manner, i.e. move the bit m7-08 to the beginning of the file name:

# Before:
Summary-building-mobile-apps-ionic-framework-angularjs-m7-08.mp4

# After:
m7-08_Summary-building-mobile-apps-ionic-framework-angularjs.mp4

This will perform a dry run, and print the new file names without actually renaming any files:

rename_files_regex.py . "([^\.]+?)-(m\\d+-\\d+)" "\\2_\\1"

This will do the actual renaming (you can use either -w or --write):

rename_files_regex.py . "([^\.]+?)-(m\\d+-\\d+)" "\\2_\\1" --write

Solution 13 - Python

You can use os.system function for simplicity and to invoke bash to accomplish the task:

import os
os.system('mv old_filename new_filename')

Solution 14 - Python

This works for me.

import os
for afile in os.listdir('.'):
	filename, file_extension = os.path.splitext(afile)
	if not file_extension == '.xyz':
		os.rename(afile, filename + '.abc')

Solution 15 - Python

What about this :

import re
p = re.compile(r'_')
p.split(filename, 1) #where filename is CHEESE_CHEESE_TYPE.***

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJeffView Question on Stackoverflow
Solution 1 - PythonMessaView Answer on Stackoverflow
Solution 2 - PythonbukzorView Answer on Stackoverflow
Solution 3 - PythonYogeesh SeralathanView Answer on Stackoverflow
Solution 4 - PythondarelfView Answer on Stackoverflow
Solution 5 - PythonAziz AltoView Answer on Stackoverflow
Solution 6 - Pythonkrs1View Answer on Stackoverflow
Solution 7 - PythonErik KaplunView Answer on Stackoverflow
Solution 8 - PythonnicholasView Answer on Stackoverflow
Solution 9 - PythonUriView Answer on Stackoverflow
Solution 10 - PythonLloydView Answer on Stackoverflow
Solution 11 - PythonTed FullerView Answer on Stackoverflow
Solution 12 - PythonccpizzaView Answer on Stackoverflow
Solution 13 - Pythonuser5449023View Answer on Stackoverflow
Solution 14 - PythonedibView Answer on Stackoverflow
Solution 15 - PythonBandanView Answer on Stackoverflow