Link to home
Start Free TrialLog in
Avatar of Stephen1991
Stephen1991

asked on

Python

How can i search / find / check if the filename ends in .txt
and then print the filename?
Avatar of farzanj
farzanj
Flag of Canada image

Try this:
import fnmatch
import os

for file in os.listdir('.'):
    if fnmatch.fnmatch(file, '*.txt'):
        print file

Open in new window

It all depends.

Under windows you might have surprises depending on what you want exactly.

Windows allows lowercase and uppercase file name, but if you ask whether
'file2.txt' exists it will tell you it does even if the file is really named 'file2.TXT'


files = [ r'C:\tmp\file.txt', r'C:\tmp\file2.TXT' ]


for file in files:
    if file.endswith(.txt'):
        print "endswith .txt", file
    if fnmatch.fnmatch(file, '*.txt'):
        print 'fnmatch .txt, file
    if file.endswith(.TXT'):
        print "endswith .TXT", file
    if file.lower().endswith(.txt'):
        print "endswith .txt (case insensitive)", file
ASKER CERTIFIED SOLUTION
Avatar of gelonida
gelonida
Flag of France image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
My above example assumes, that you have already a file list.

If you don't have the file list, then you might even do something else and directly get the files that you want.

If it is in only one directory, then you can use glob.

import glob
print glob.glob(r'E:\windows\*.dll') # only files ending with '*.dll'
Avatar of Stephen1991
Stephen1991

ASKER

How bout if i'm trying to get this code to only return .txt files? tried using the fnmatch but it wouldnt work?
import os

def main():
    path = os.path.join(os.environ['SANDBOX'],'CS402')   
    for root, dirs, files, in os.walk(path):
        print
        print root
        for filename in files:
            print "     ", filename           
        
main()

Open in new window

I think i got it to work, but i dont think it is case sensitive
import os
import fnmatch


def main():
    path = os.path.join(os.environ['SANDBOX'],'CS402')   
    for root, dirs, files, in os.walk(path):
        print
        print root
        for filename in files:
            filename.lower()
            if filename.endswith('.txt'):
                print "     ", filename
            
        
main()

Open in new window

You can also use the os.path.splitext(fname)  (http://docs.python.org/library/os.path.html#os.path.splitext) to get the extension for testing -- instead of .endswith().  Having the string with the extension only, you can create your own regular expression to accept some extensions or case sensitively or case insensitively.  It all depends on how many files must be processed/tested and how often the Python program is to be called.  The str.lower() may still be more efficient.  Anyway, the case sensitiveness problem is OS dependent or the problem of a design decision.

c:\tmp>python
Python 2.7.2 (default, Jun 12 2011, 14:24:46) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import this

Open in new window


displays...


The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

"...refuse the temptation to guess" -- for which way is better.  If more solutions look nicely, just measure the performance.
I agree with pep's comment about readability:

if file.lower().endswith('.txt')::
is perhaps not that intuitive

on the other hand it's debatable whether
    if filename.endswith(suffix):
or
   if os.path.splitext('bla.dd')[1] == suffix:


I'm a little surprised that fnmatch didn't work for you though.

I would expect, that
if fnmatch.fnmatch(file, '*.txt'):
should be working

both lack however the case sensitivity issue, which you might encounter if you were interested in


import os
import fnmatch

 
def get_files_with_suffix(path, suffix):
      """ generator returning files with a certain 
          suffix below a given path 
      """
      for root, dirs, files, in os.walk(path):
        for filename in files:
            filename.lower()
            if filename.endswith(suffix):
            # alternative if statements would be
            # if os.path.splitext(filename)[1] == suffix:
            # if fnmatch.fnmatch(filename, '*' + suffix):
                yield os.path.join(root, filename)
            

def main():
    path = os.path.join(os.environ['SANDBOX'],'CS402')
    for filename in get_files_with_suffix(path, '.txt'):
        print filename
   
main()

Open in new window