5

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:

  1. the script currently must be inside my directory for it to run.
  2. 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.

3
  • newname = 'file_' + filename should work. You don't need the str() because filename refers to a string already, but even so that should have worked. Maybe you tried it outside the loop? Commented Jan 23, 2016 at 6:34
  • You were right it was outside of my loop Commented Jan 23, 2016 at 7:34
  • One other comment: please be careful of indentation when posting code. You know that it is critical in Python. The code shown, for example, will not compile as it is. Commented Jan 23, 2016 at 8:18

4 Answers 4

5

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'))
Sign up to request clarification or add additional context in comments.

Comments

3

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.

4 Comments

Tried this and name is then undefined.
Much simpler to declare those extensions. -thank you for the suggestion.
Traceback (most recent call last): File "C:/Users/dana/Desktop/scott_suffix_change2.py", line 16, in <module> os.rename(os.path.join(path, filename), os.path.join(name, newname)) NameError: name 'name' is not defined
Sorry. Typo. Updated my answer. Not name but path.
1
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

Comments

0
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.

1 Comment

That is an interesting approach and very informative. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.