I am learning Python and I have been tasked with:
adding "file_" to the beginning of each name in a directory
changing the extension (directory contains 4 different types currently: .py, .TEXT, .rtf, .text)
I have many files, all with different names, each 7 characters long. I was able to change the extensions but it feels very clunky. I am positive there is a cleaner way to write the following (but its functioning, so no complaints on that note):
import os, sys
path = 'C:/Users/dana/Desktop/text_files_2/'
for filename in os.listdir(path):
if filename.endswith('.rtf'):
newname = filename.replace('.rtf', '.txt')
os.rename(filename, newname)
elif filename.endswith('.py'):
newname = filename.replace('.py', '.txt')
os.rename(filename, newname)
elif filename.endswith('.TEXT'):
newname = filename.replace('.TEXT', '.txt')
os.rename(filename, newname)
elif filename.endswith('.text'):
newname = filename.replace('.text', '.txt')
os.rename(filename, newname)
I do still have a bit of a problem:
the script currently must be inside my directory for it to run.
I can not figure out how to add "file_" to the start of each of the filenames [you would think that would be the easy part]. I have tried declaring newname as
newname = 'file_' + str(filename)
it then states filename is undefined.
Any assistance on my two existing issues would be greatly appreciated.
The basic idea would be first get the file extension part and the real file name part, then put the filename into a new string.
os.path.splitext(p) method will help to get the file extensions, for example: os.path.splitext('hello.world.aaa.txt') will return ['hello.world.aaa', '.txt'], it will ignore the leading dots.
So in this case, it can be done like this:
import os
import sys
path = 'C:/Users/dana/Desktop/text_files_2/'
for filename in os.listdir(path):
filename_splitext = os.path.splitext(filename)
if filename_splitext[1] in ['.rtf', '.py', '.TEXT', '.text']:
os.rename(os.path.join(path, filename),
os.path.join(path, 'file_' + filename_splitext[0] + '.txt'))
Supply the full path name with os.path.join():
os.rename(os.path.join(path, filename), os.path.join(name, newname))
and you can run your program from any directory.
You can further simply your program:
extensions = ['.rtf', '.py', '.TEXT', '.text']
for extension in extensions:
if filename.endswith(extension):
newname = filename.replace(extension, '.txt')
os.rename(os.path.join(path, filename), os.path.join(path, newname))
break
All the other elif statements are not needed anymore.
import glob, os
path = 'test/'# your path
extensions = ['.rtf', '.py', '.TEXT', '.text']
for file in glob.glob(os.path.join(path, '*.*')):
file_path, extension = os.path.splitext(file)
if extension in extensions:
new_file_name = '{0}.txt'.format(
os.path.basename(file_path)
)
if not new_file_name.startswith('file_'): # check if file allready has 'file_' at beginning
new_file_name = 'file_{0}'.format( # if not add
new_file_name
)
new_file = os.path.join(
os.path.dirname(file_path),
new_file_name
)
os.rename(file, new_file)
file_path, extension = os.path.splitext(file) getting file path without extension and extension f.e ('dir_name/file_name_without_extension','.extension')
os.path.dirname(file_path) getting directory f.e if file_path is dir1/dir2/file.ext result will be 'dir1/dir2'
os.path.basename(file_path) getting file name without extension
import os, sys
path = 'data' // Initial path
def changeFileName( path, oldExtensions, newExtension ):
for name in os.listdir(path):
for oldExtension in oldExtensions:
if name.endswith(oldExtension):
name = os.path.join(path, name)
newName = name.replace(oldExtension, newExtension)
os.rename(name, newName)
break;
if __name__ == "__main__":
changeFileName( 'data', ['.py', '.rtf' , '.text', '.TEXT'], '.txt')
Use an array to store all the old extensions and iterate through them.
Related
My problem is to get ONLY files without extensions.
I mean - I have a dictionary and there are some files without extensions and some files with extensions (.xml, .csv, etc)
I want that my code would only read files without extensions.
Now, it's reading every file in the dictionary "Dir".
path = 'C:/Users/STJ2TW/Desktop/Dir/'
for filename in os.listdir(path):
fullname = os.path.join(path, filename)
Thanks in advance!
You can split the filename using the splittext function and check for the ones which are not a directory and do not have an extension value (ext).
import os
path = os.getcwd()
for filename in os.listdir(path):
if not os.path.isdir(filename):
(name, ext) = os.path.splitext(filename)
if not ext:
# Your code here
If there are no dots in your files, you can do :
path = 'C:/Users/STJ2TW/Desktop/Dir/'
for filename in os.listdir(path):
if '.' not in filename:
fullname = os.path.join(path, filename)
I am trying to copy all jpeg files from a directory (with multiple subdirectories) to a single directory. There are multiple files with the same name, so I am trying to rename the files using the name of the parent directory. For example: c:\images\tiger\image_00001.jpg will be moved to a new folder and renamed to c:\images\allimages\tiger_image_00001.jpg. I tried the code below, but nothing happens. The folder gets created, but the files do not move. This is what I have so far:
import os
path = 'source/'
os.mkdir('source/allimages/')
extensions = ['.jpeg']
for folder, _, filenames in os.walk(path):
for filename in filenames:
if folder == path or folder == os.path.join(path, 'allimages'):
continue
folder = folder.strip(path)
extension = os.path.splitext(os.path.splitext(filename)[0])[-1].lower()
if extension in extensions:
infilename = os.path.join(path, folder, filename)
newname = os.path.join(path, 'all_files', "{}-{}".format(folder.strip('./')))
os.rename(infilename, newname)
I would recommend having a function dedicated to resolving a unique filename. A while loop should do the trick. This should work.
import os
import shutil
def resolve_path(filename, destination_dir):
dest = os.path.join(destination_dir, filename)
*base_parts, extension = filename.split('.')
base_name = '.'.join(base_parts)
duplicate_num = 1
while os.path.exists(dest):
new_base = base_name + str(duplicate_num).zfill(5)
new_filename = "{}.{}".format(new_base, extension)
dest = os.path.join(destination_dir, new_filename)
duplicate_num += 1
return dest
That is such that the following is the result....
>>> with open('/path/to/file.extension', 'w') as f:
>>> pass # just create the file
>>> resolve_path('file.extension', '/path/to/')
'/path/to/file00001.extension'
Then put it together with traversing the source...
def consolidate(source, destination, extension='.jpg'):
if not os.path.exists(destination):
os.makedirs(destination)
for root, dirs, files in os.walk(source):
for f in files:
if f.lower().endswith(extension):
source_path = os.path.join(root, f)
destination_path = resolve_path(f, destination)
shutil.copyfile(source_path, destination_path)
You're calling splitext on its own output, which doesn't get what you want:
In [4]: os.path.splitext(os.path.splitext('foo.bar')[0])[-1]
Out[4]: ''
You just want extension = os.path.splitext(filename)[-1].lower(), or if you don't want the dot, then extension = os.path.splitext(filename)[-1].lower()[1:].
(Edited) more seriously, there's a problem with folder.strip(path): this will remove all characters in path from folder. For instance 'source/rescue'.strip('source/') == ''. What you want is folder.replace(path, '').
I am thinking this code should take all my files within the folder, and rename .pdf_(date) to .pdf. However, it is not.
import os,sys
folder = 'C:\/MattCole\/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('.pdf*', '.pdf')
output = os.rename(infilename, newname)
Example: file1.pdf_20160614-050421 renamed to file.pdf
There would be multiple files in the directory. Can someone tell me what I am doing wrong? I have also tried counting the extension and used '.pdf????????????', '.pdf'
This is a bit silly, you've got some perfectly good code here that you're not using. You should use it.
import os,sys
folder = 'C:\/MattCole\/test'
for filename in os.listdir(folder):
infilename = os.path.join(folder,filename)
if os.path.isfile(infilename):
oldbase, oldext = os.path.splitext(infilename)
if oldext.startswith('.pdf'):
output = os.rename(infilename, oldbase+'.pdf')
You want to split the old file name on _, then take the first part as new name:
>>> old_name = 'file1.pdf_20160614-050421'
>>> new_name = old_name.split('_')[0]
>>> new_name
'file1.pdf'
I'd like to change the files whose extension are '.test.txt' into '.txt'.
As my codes as below, it cannot work cause invalid syntax happened to the place of 'if'.
Could you please figure out it?
Thank you so much.
import sys
import os
path = "Dir"
for(dirpath,dirnames,files)in os.walk(path):
for filename in files:
filepath = os.path.join(dirpath,filename)
if '.test.txt' in filename:
newfilename = filename.replace('.test.txt','.txt')
os.rename(filename,newfilename)
this should work...
import sys
import os
path = r"Dir"
for dirpath,dirnames,files in os.walk(path):
for filename in files:
filepath = os.path.join(dirpath,filename)
if '.test.txt' in filename:
newfilename = filename.replace('.test.txt','.txt')
newfilepath = os.path.join(dirpath, newfilename)
os.rename(filepath, newfilepath)
you did not define the new file path, in renaming action you have to supply the full file path, os.rename(src_path, dest_path)
I need to simply add the word "_Manual" onto the end of all the files i have in a specific directory
Here is the script i am using at the moment - i have no experience with python so this script is a frankenstine of other scripts i had lying around!
It doesn't give any error messages but it also doesnt work..
folder = "C:\Documents and Settings\DuffA\Bureaublad\test"
import os, glob
for root, dirs, filenames in os.walk(folder):
for filename in filenames:
filename_split = os.path.splitext(filename) # filename and extensionname (extension in [1])
filename_zero = filename_split[0]
os.rename(filename_zero, filename_zero + "_manual")
I am now using
folder = "C:\Documents and Settings\DuffA\Bureaublad\test"
import os # glob is unnecessary
for root, dirs, filenames in os.walk(folder):
for filename in filenames:
fullpath = os.path.join(root, filename)
filename_split = os.path.splitext(fullpath) # filename and extensionname (extension in [1])
filename_zero, fileext = filename_split
print fullpath, filename_zero + "_manual" + fileext
os.rename(fullpath, filename_zero + "_manual" + fileext)
but it still doesnt work..
it doesnt print anything and nothing gets changed in the folder!
os.rename requires a source and destination filename. The variable filename contains your current filename (e.g., "something.txt"), whereas your split separates that into something and txt. As the source file to rename, you then only specify something, which fails silently.
Instead, you want to rename the file given in filename, but as you walk into subfolders as well, you need to make sure to use the absolute path. For this you can use os.path.join(root, filename).
So in the end you get something like this:
os.rename(os.path.join(root, filename),
os.path.join(root, filename_zero + "_manual" + filename_split[1]))
This would rename dir1/something.txt into dir1/something_manual.txt.
folder = r"C:\Documents and Settings\DuffA\Bureaublad\test"
import os, glob
for root, dirs, filenames in os.walk(folder):
for filename in filenames:
filename_split = os.path.splitext(filename) # filename and extensionname (extension in [1])
filename_zero = filename_split[0]
os.rename(os.path.join(root, filename), os.path.join(root, filename_zero + "_manual" + filename_split[1]))
In your code, you are trying to rename filename_zero, which is the filename without extension and therefore does not exist as a real path. You have to specify the full path to os.rename like above.
I. e. it does nothing? Let's see:
folder = "C:\Documents and Settings\DuffA\Bureaublad\test"
import os # glob is unnecessary
for root, dirs, filenames in os.walk(folder):
for filename in filenames:
fullpath = os.path.join(root, filename)
filename_split = os.path.splitext(fullpath) # filename and extensionname (extension in [1])
filename_zero, fileext = filename_split
os.rename(fullpath, filename_zero + "_manual" + fileext)
might do the trick, as you have to work with the full path. but I don't understand why there was no exception when the files could not be found...
EDIT to put the change to a more prominent place:
You as well seem to have your path wrong.
Use
folder = r"C:\Documents and Settings\DuffA\Bureaublad\test"
to prevent that the \t is turned into a tab character.
for root, dirs, filenames in os.walk(folder):
for filename in filenames:
os.rename(os.path.join(root,filename),
os.path.join(root,'%s_manual%s' % os.path.splitext(filename)))
you should add a control in your code, to verify that the filename to rename hasn't already '_manual' in its string name