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.
15 Answers
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 4Here'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)) 0The 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_")) 0Assuming 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:]) 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_', '')) 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.
2This 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 !.
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) 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.
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()
This command will remove the initial "CHEESE_" string from all the files in the current directory, using renamer:
$ renamer --find "/^CHEESE_/" * 1I 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 1You can use os.system function for simplicity and to invoke bash to accomplish the task:
import os os.system('mv old_filename new_filename') 1This 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') What about this :
import re p = re.compile(r'_') p.split(filename, 1) #where filename is CHEESE_CHEESE_TYPE.*** 1