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))
Related
Suppose from index.py with CGI, I have post file foo.fasta to display file. I want to change foo.fasta's file extension to be foo.aln in display file. How can I do it?
An elegant way using pathlib.Path:
from pathlib import Path
p = Path('mysequence.fasta')
p.rename(p.with_suffix('.aln'))
os.path.splitext(), os.rename()
for example:
# renamee is the file getting renamed, pre is the part of file name before extension and ext is current extension
pre, ext = os.path.splitext(renamee)
os.rename(renamee, pre + new_extension)
import os
thisFile = "mysequence.fasta"
base = os.path.splitext(thisFile)[0]
os.rename(thisFile, base + ".aln")
Where thisFile = the absolute path of the file you are changing
Starting from Python 3.4 there's pathlib built-in library. So the code could be something like:
from pathlib import Path
filename = "mysequence.fasta"
new_filename = Path(filename).stem + ".aln"
https://docs.python.org/3.4/library/pathlib.html#pathlib.PurePath.stem
I love pathlib :)
Use this:
os.path.splitext("name.fasta")[0]+".aln"
And here is how the above works:
The splitext method separates the name from the extension creating a tuple:
os.path.splitext("name.fasta")
the created tuple now contains the strings "name" and "fasta".
Then you need to access only the string "name" which is the first element of the tuple:
os.path.splitext("name.fasta")[0]
And then you want to add a new extension to that name:
os.path.splitext("name.fasta")[0]+".aln"
As AnaPana mentioned pathlib is more new and easier in python 3.4 and there is new with_suffix method that can handle this problem easily:
from pathlib import Path
new_filename = Path(mysequence.fasta).with_suffix('.aln')
Using pathlib and preserving full path:
from pathlib import Path
p = Path('/User/my/path')
new_p = Path(p.parent.as_posix() + '/' + p.stem + '.aln')
Sadly, I experienced a case of multiple dots on file name that splittext does not worked well... my work around:
file = r'C:\Docs\file.2020.1.1.xls'
ext = '.'+ os.path.realpath(file).split('.')[-1:][0]
filefinal = file.replace(ext,'')
filefinal = file + '.zip'
os.rename(file ,filefinal)
>> file = r'C:\Docs\file.2020.1.1.xls'
>> ext = '.'+ os.path.realpath(file).split('.')[-1:][0]
>> filefinal = file.replace(ext,'.zip')
>> os.rename(file ,filefinal)
Bad logic for repeating extension, sample: 'C:\Docs\.xls_aaa.xls.xls'
I want to Make a Python program that takes a folder name from the input argument, and then renames all its files by adding an "_{n}" at the end of it where n is the serial of that file. For example, if folder "images" contained, "images/cat.jpg", "images/dog.jpg", then after running the command, it will have "images/cat_1.jpg", "images/dog_2.jpg" . Sort the files according to last accessed date. I tried the problem partially as following:-
import os
from os import rename
from os.path import basename
path = os.getcwd()
filenames =next(os.walk(path))[2]
countfiles=len(filenames)
for filename in filenames:
fname=os.path.splitext(filename)[0]
ext=os.path.splitext(filename)[1]
old=fname+ext
new=fname + '_' +ext
os.rename(old, new)
this can rename the file adding an under score at the end of file name.However, I have no idea to add serial of files after the underscore. I would like to know how to batch rename the files using a simple Python script. I would appreciate any advice.
Thank you!
Have you tried something like:
import os
filepath = 'C:/images/'
os.chdir(filepath)
for num, filename in enumerate(os.listdir(os.getcwd()), start= 1):
fname, ext = filename, ''
if '.' in filename:
fname, ext = filename.split('.')
os.rename(filename, fname + '_%s' %num + '.' + ext)
I am new to Python coding so here a question. I want to find files that are called "untitled" with any kind of extension, e.g. jpg, indd, psd. Then rename them to the date of the current day.
I have tried the following:
import os
for file in os.listdir("/Users/shirin/Desktop/Artez"):
if file.endswith("untitled.*"):
print(file)
When I run the script, nothing happens.
You might find the glob function more useful in this situation:
import glob
for file in glob.glob("/Users/shirin/Desktop/Artez/untitled.*"):
print(file)
Your function does not print anything as there are probably no files ending with .* in the name. The glob.glob() function will carry out the file expansion for you.
You can then use this to do your file renaming as follows:
import glob
import os
from datetime import datetime
current_day = datetime.now().strftime("%Y-%m-%d")
for source_name in glob.glob("/Users/shirin/Desktop/Artez/untitled.*"):
path, fullname = os.path.split(source_name)
basename, ext = os.path.splitext(fullname)
target_name = os.path.join(path, '{}{}'.format(current_day, ext))
os.rename(source_name, target_name)
A Python datetime object can be used to get you a suitable timestamp.
Python string comparator does not support wildcards. You can search for "untitled." anywhere in the text:
import os
for file in os.listdir("/Users/shirin/Desktop/Artez"):
if "untitled." in file:
print(file)
keep in mind that this will include any file that has "untitled." at any location of the file.
try with this approach
import os
directoryPath = '/Users/shirin/Desktop/Artez'
lstDir = os.walk(directoryPath)
for root, dirs, files in lstDir:
for fichero in files:
(filename, extension) = os.path.splitext(fichero)
if filename.find('untitle') != -1: # == 0 if starting with untitle
os.system('mv '+directoryPath+filename+extension+' '+directoryPath+'$(date +"%Y_%m_%d")'+filename+extension)
import os
for file in os.listdir("/Users/shirin/Desktop/Artez"):
if(file.startswith("untitled")):
os.rename(file, datetime.date.today().strftime("%B %d, %Y") + "." + file.split(".")[-1])
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)
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.***