10

I'm still new to Python (using 2.6) and I am trying to do a system wide search for a file when just the filename is available and return the absolute path on windows. I've searched and found some modules like scriptutil.py and looked through the os module but haven't found anything that suits my needs (or I may not have understood everything correctly to apply it to what I need and thus have not included any code). I would appreciate any help.

Thanks.

ldmvcd
  • 968
  • 3
  • 10
  • 15

3 Answers3

17

The os.walk() function is one way of doing it.

import os
from os.path import join

lookfor = "python.exe"
for root, dirs, files in os.walk('C:\\'):
    print "searching", root
    if lookfor in files:
        print "found: %s" % join(root, lookfor)
        break
Martin Stone
  • 12,682
  • 2
  • 39
  • 53
  • 1
    @ Martin Stone Yes it is, but it requires a path, or else is searches only the current working directory (if I understand correctly) – ldmvcd Mar 01 '11 at 10:42
  • @ldmvcd, it searches recursively from the directory you tell it to start in. – Martin Stone Mar 01 '11 at 11:21
  • @Martin Stone **break** should be removed, because there could be several files with the same name in different directories – eyquem Mar 01 '11 at 11:57
  • @Martin Stone, thank you for the code, I guess you've already tried it, but for me the search is not successful. It seems to be only searching and listing directories and not the actual files. It thus does not find a match for the second print statement to print. – ldmvcd Mar 01 '11 at 12:05
  • 2
    @Martin Stone, my apologies, I take that back. Your code does whats its supposed to be doing. Thank you! – ldmvcd Mar 01 '11 at 12:19
4

You could start at the root directory and recursively walk the directory structure looking at each level for the file. Of course if you want to search your entire system you will need to call this for each drive.

os.path.walk(rootdir,f,arg)

There's a good answer to a similar question here and another one here

Community
  • 1
  • 1
Peter Kelly
  • 14,253
  • 6
  • 54
  • 63
  • thank you for the links, they were helpful just like the answer posted above. – ldmvcd Mar 01 '11 at 12:20
  • Using `os.path.walk`, which requires 3 arguments, has been deprecated since Python 2.3 (and removed entirely in 3.0) in favor of `os.walk`, which only requires 1 argument (and has 3 optional). – ArtOfWarfare Oct 11 '15 at 23:30
0

Would something like this work?

import os
import sys
import magic
import time
import fnmatch

class FileInfo(object):

    def __init__(self, filepath):
        self.depth = filepath.strip('/').count('/')
        self.is_file = os.path.isfile(filepath)
        self.is_dir = os.path.isdir(filepath)
        self.is_link = os.path.islink(filepath)
        self.size = os.path.getsize(filepath)
        self.meta = magic.from_file(filepath).lower()
        self.mime = magic.from_file(filepath, mime=True)
        self.filepath = filepath


    def match(self, exp):
        return fnmatch.fnmatch(self.filepath, exp)

    def readfile(self):
        if self.is_file:
            with open(self.filepath, 'r') as _file:
                return _file.read()

    def __str__(self):
        return str(self.__dict__)



def get_files(root):

    for root, dirs, files in os.walk(root):

        for directory in dirs:
            for filename in directory:
                filename = os.path.join(root, filename)
                if os.path.isfile(filename) or os.path.isdir(filename):
                    yield FileInfo(filename)

        for filename in files:
            filename = os.path.join(root, filename)
            if os.path.isfile(filename) or os.path.isdir(filename):            
                yield FileInfo(filename)


for this in get_files('/home/ricky/Code/Python'):
    if this.match('*.py'):
        print this.filepath
Ricky Wilson
  • 3,187
  • 4
  • 24
  • 29