Renaming multiple files in python, identical names but different extensions - python

I'm trying to change the name of multiple files that all have identical names but various extensions, I get the impression there there is a simple streamlined method of doing this but I can't figure out how.
At present my code looks like this;
import os
def rename_test():
os.rename ('cheddar.tasty.coor', 'newcheddar.vintage.coor')
os.rename ('cheddar.tasty.txt', 'newcheddar.vintage.txt')
os.rename ('cheddar.tasty.csv', 'newcheddar.vintage.csv')
rename_test()

import os
def rename(dirpath):
whitelist = set('txt csv coor'.split())
for fname in os.listdir(dirpath):
name, cat, ext = os.path.basename(os.path.join(dirpath, fname)).rsplit(os.path.extsep,2)
if ext not in whitelist:
continue
name = 'new' + name
cat = 'vintage'
newname = os.path.extsep.join([name, cat, ext])
os.rename(os.path.join(dirpath, fname), os.path.join(dirpath, newname))

You might use the glob module. It really depends on what you want to improve.
for ext in ('*.coor', '*.txt', '*.csv'):
for filename in glob.glob(ext):
newname = filename.replace("cheddar.", "newcheddar.").replace(".tasty.", ".vintage.")
os.rename(filename, newnew)

def rename_test():
for ext in "coor txt csv".split():
os.rename('cheddar.tasty.'+ext, 'newcheddar.vintage.'+ext)

I would use listdir and replace - no regular expressions, no having to parse the filename twice. Just one replace and an equality test:
import os
for old_filename in os.listdir('.'):
new_filename = old_filename.replace('cheddar.tasty', 'newcheddar.vintage')
if new_filename != old_filename:
os.rename(old_filename, new_filename)

Related

Rename files from lower to upper with Python

How can I rename many files from lower to upper?
For example a file named example.txt to EXAMPLE.txt
I would use pathlib for this. You'll have to modify this to suit your needs - In this example I'm just using pathlib.Path.glob to iterate through all .txt files in the current working directory:
from pathlib import Path
for path in Path(".").glob("*.txt"):
path.rename(f"{path.stem.upper()}{path.suffix}")
For easy solution, you can try:
import os
fileName = 'example.txt'
def toUpper(fileName):
tempName = fileName.split('.')
return (tempName[0].upper() + '.' + tempName[1])
os.rename(fileName, toUpper(fileName))
It won't work if your file name has multiple dots.
import re
import os
def get_name(original_file_name):
name, ext = (re.match('(.*)(\.[^.]+)', original_file_name).groups())
return name.upper() + ext
def rename_file(original_file_name):
os.rename(original_file_name, get_name(original_file_name))

Most Pythonic and fastest way to change a file name extension, if it's uppercase, to lower case

I have a list of files and some of them have upper case file name extensions, eg file.PDF. In these cases, i would like to change the upper case to lower case, eg file.pdf
I came up with this solution
currentDir = 'theDirectory'
for file in os.listdir(currentDir):
print(file)
if file[-3:] == 'PDF':
oldName = currentDir+'/'+file
newName = currentDir+'/'+file[:-3]+'pdf'
os.rename( oldName , newName )
I'll be dealing with millions of files, daily, so it's important that it's the most efficient method possible.
Is there a better way than the solution above ?
This might work, making use of os.path.splitext().
currentDir = 'theDirectory'
for file in os.listdir(currentDir):
print(file)
newExt=os.path.splitext(file)[1].lower()
oldName = currentDir+'/'+file
newName = os.path.splitext(file)[0]+newExt
os.rename( oldName , newName )
You can also try with the pathlib library in Python 3
from pathlib import Path
dir_path = "C:/temp"
results = [x.rename(x.joinpath(x.parent,str(x.name).split(".")[0]+"."+str(x.name).split(".")[1].lower())) for x in Path(dir_path).iterdir() if x.is_file()]
Hope it helps.
if you want lowercase all of the extensions, not just 'PDF', or/and have some more control on renaming most simple, intuitive and self-descriptive base of solution is
def lowercase_exts(folder):
for fname in os.listdir(folder):
name, ext = os.path.splitext(fname)
os.rename(os.path.join(folder, fname), os.path.join(folder, name + ext.lower()))
But if you need just efficiently rename millions of pdf on windows
import os
import subprocess
os.chdir(folder)
subprocess.call('ren *.PDF *.pdf', shell=True)

Is there a way to remove the extension from all files in a folder? [duplicate]

I would like to change the extension of the files in specific folder. i read about this topic in the forum. using does ideas, I have written following code and I expect that it would work but it does not. I would be thankful for any guidance to find my mistake.
import os,sys
folder = 'E:/.../1936342-G/test'
for filename in os.listdir(folder):
infilename = os.path.join(folder,filename)
if not os.path.isfile(infilename): continue
oldbase = os.path.splitext(filename)
infile= open(infilename, 'r')
newname = infilename.replace('.grf', '.las')
output = os.rename(infilename, newname)
outfile = open(output,'w')
The open on the source file is unnecessary, since os.rename only needs the source and destination paths to get the job done. Moreover, os.rename always returns None, so it doesn't make sense to call open on its return value.
import os
import sys
folder = 'E:/.../1936342-G/test'
for filename in os.listdir(folder):
infilename = os.path.join(folder,filename)
if not os.path.isfile(infilename): continue
oldbase = os.path.splitext(filename)
newname = infilename.replace('.grf', '.las')
output = os.rename(infilename, newname)
I simply removed the two open. Check if this works for you.
You don't need to open the files to rename them, os.rename only needs their paths. Also consider using the glob module:
import glob, os
for filename in glob.iglob(os.path.join(folder, '*.grf')):
os.rename(filename, filename[:-4] + '.las')
Something like this will rename all files in the executing directory that end in .txt to .text
import os, sys
for filename in os.listdir(os.path.dirname(os.path.abspath(__file__))):
base_file, ext = os.path.splitext(filename)
if ext == ".txt":
os.rename(filename, base_file + ".text")
import os
dir =("C:\\Users\\jmathpal\\Desktop\\Jupyter\\Arista")
for i in os.listdir(dir):
files = os.path.join(dir,i)
split= os.path.splitext(files)
if split[1]=='.txt':
os.rename(files,split[0]+'.csv')
#!/usr/bin/env python
'''
Batch renames file's extension in a given directory
'''
import os
import sys
from os.path import join
from os.path import splitext
def main():
try:
work_dir, old_ext, new_ext = sys.argv[1:]
except ValueError:
sys.exit("Usage: {} directory old-ext new-ext".format(__file__))
for filename in os.listdir(work_dir):
if old_ext == splitext(filename)[1]:
newfile = filename.replace(old_ext, new_ext)
os.rename(join(work_dir, filename), join(work_dir, newfile))
if __name__ == '__main__':
main()
If you have python 3.4 or later, you can use pathlib. It is as follows. This example is for changing .txt to .md.
from pathlib import Path
path = Path('./dir')
for f in path.iterdir():
if f.is_file() and f.suffix in ['.txt']:
f.rename(f.with_suffix('.md'))
With print and validation.
import os
from os import walk
mypath = r"C:\Users\you\Desktop\test"
suffix = ".png"
replace_suffix = ".jpg"
filenames = next(walk(mypath), (None, None, []))[2]
for filename in filenames:
if suffix in filename:
print(filename)
rep = input('Press y to valid rename : ')
if rep == "y":
for filename in filenames:
if suffix in filename:
os.rename(mypath+"\\"+filename, mypath+"\\"+filename.replace(suffix, replace_suffix))

how to delete hyphen in filename and add something to the name ? python

i have a folder with a lot of files like that:
2012-05-09.txt
2012-05-10.txt
2012-05-11.txt
etc.
now i wanna delete the hyphen and add " _PHOTOS_LOG " that it looks in the end like this:
20120509_PHOTOS_LOG.txt
20120510_PHOTOS_LOG.txt
20120511_PHOTOS_LOG.txt
etc.
How to do ?
thats the code now:
//updated the code, now its working
import os
import glob
import os.path
import sys
src = 'D:\\testing/hyphen1'
src = r'D:\testing\test'
for fn in os.listdir(src):
new_filename = fn.replace('-','').replace('.txt', '_PHOTOS_LOG.txt')
fn = os.path.join(src, fn)
new_filename = os.path.join(src, new_filename)
try:
os.rename(fn, new_filename)
except (WindowsError, OSError):
print 'Error renaming "%s" to "%s"' % (fn, new_filename)
print sys.exc_info()[1]
You could do the rename something like this:
import os
for filename in os.listdir("."):
if filename.endswith(".txt"):
newFilename = filename.replace("-", "")
os.rename(filename, newFilename[:7]+"_PHOTO_LOG.txt")
os.listdir(".") returns the names of the entries in the current folder
filename.endswith(".txt") verifies if the filename is one of your text files
if it is, it removes the - and adds the _PHOTO_LOG at the end
new_filename = old_filename.replace("-", "").replace(".txt", "_PHOTOS_LOG.txt")
That will get you the new filename, if you want to rename all the files, then:
import os
for old_filename in os.listdir("."):
new_filename = old_filename.replace("-", "").replace(".txt", "_PHOTOS_LOG.txt")
os.rename(old_filename, new_filename)
For all of your files in your current directory:
import os
for fn in os.listdir('.'):
new_filename = fn.replace('-','').replace('.txt', '_PHOTOS_LOG.txt')
os.rename(fn, new_filename)
Using os.rename() to change the filenames.
The individual file names will end up a series of strings, so while you usually would want to use methods from the os module, you can simply treat these as strings since you are not looking at paths, but simple filenames and use replace() to create the new names.
--
Example for one filename to show transformation:
fn ='2012-05-09.txt'
then
fn.replace('-','').replace('.txt', '_PHOTOS_LOG.txt')
will yield '20120509_PHOTOS_LOG.txt'
You need to iterate through the list of files
and rename them according to your needs:
import os
import glob
for name in glob.glob('*.txt'):
newname = "%s_PHOTOS_LOG.txt" % name.replace('-','')[:-4]
os.rename(name, newname)
The glob.glob function produces a list of .txt files in the current directory.

Rename multiple files in a directory in Python

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.
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
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))
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_"))
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:])
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.
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
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_/" *
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
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')
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')
What about this :
import re
p = re.compile(r'_')
p.split(filename, 1) #where filename is CHEESE_CHEESE_TYPE.***

Categories