64

I'd like to check if there are any .rar files in a directory. It doesn’t need to be recursive.

Using wildcard with os.path.isfile() was my best guess, but it doesn't work. What can I do then?

Alex Weitz
  • 3,199
  • 4
  • 34
  • 57
Alex
  • 823
  • 2
  • 7
  • 6

8 Answers8

109

glob is what you need.

>>> import glob
>>> glob.glob('*.rar')   # all rar files within the directory, in this case the current working one

os.path.isfile() returns True if a path is an existing regular file. So that is used for checking whether a file already exists and doesn't support wildcards. glob does.

user225312
  • 126,773
  • 69
  • 172
  • 181
  • 1
    +1 you just beat me to it while I was trying to pull a complete answer. – pyfunc Nov 28 '10 at 09:21
  • 2
    Unfortunately, without using os.path.isfile() to check the results, you still don't know whether what you've found are directories or files. – Peter Hansen Nov 28 '10 at 17:03
19

Without using os.path.isfile() you won't know whether the results returned by glob() are files or subdirectories, so try something like this instead:

import fnmatch
import os

def find_files(base, pattern):
    '''Return list of files matching pattern in base folder.'''
    return [n for n in fnmatch.filter(os.listdir(base), pattern) if
        os.path.isfile(os.path.join(base, n))]

rar_files = find_files('somedir', '*.rar')

You could also just filter the results returned by glob() if you like, and that has the advantage of doing a few extra things relating to unicode and the like. Check the source in glob.py if it matters.

[n for n in glob(pattern) if os.path.isfile(n)]
Peter Hansen
  • 21,046
  • 5
  • 50
  • 72
10
import os
[x for x in os.listdir("your_directory") if len(x) >= 4 and  x[-4:] == ".rar"]
Mariy
  • 5,746
  • 4
  • 40
  • 57
7

Wildcards are expanded by shell and hence you can not use it with os.path.isfile()

If you want to use wildcards, you could use popen with shell = True or os.system()

>>> import os
>>> os.system('ls')
aliases.sh          
default_bashprofile     networkhelpers          projecthelper.old           pythonhelpers           virtualenvwrapper_bashrc
0
>>> os.system('ls *.old')
projecthelper.old
0

You could get the same effect with glob module too.

>>> import glob
>>> glob.glob('*.old')
['projecthelper.old']
>>> 
pyfunc
  • 65,343
  • 15
  • 148
  • 136
4

If you just care about whether at least one file exists and you don't want a list of the files:

import glob
import os

def check_for_files(filepath):
    for filepath_object in glob.glob(filepath):
        if os.path.isfile(filepath_object):
            return True

    return False
Tchotchke
  • 3,061
  • 3
  • 22
  • 37
0

to display full path and filter based on extension,

import os
onlyfiles = [f for f in os.listdir(file) if len(f) >= 5 and  f[-5:] == ".json" and isfile(join(file, f))]
Som
  • 1,467
  • 13
  • 11
-1

iglob is better than glob here since you do not actually want the full list of rar files, but just want to check that one rar exists

gnetscher
  • 101
  • 1
  • 1
  • 6
  • 6
    While this is actually true, this answer would benefit from a more-detailed explanation. The difference is that `iglob` returns an iterator, so if you call it once and it returns something, you know there was at least one match. – tripleee Aug 12 '16 at 04:29
-1

Just another method to get the job done using subprocess.

import subprocess

try:
        q = subprocess.check_output('ls')
        if ".rar" in q:
             print "Rar exists"
except subprocess.CalledProcessError as e:
        print e.output

Reference : https://docs.python.org/2/library/subprocess.html#subprocess.check_output