[Python编程(第4版)].(Programming.Python.4th.Edition).Mark.Lutz.文字版

(yzsuai) #1

instance, the following Unix command line would pinpoint lines and files at and below
the current directory that mention the string popen:


find. -name "*.py" -print -exec fgrep popen {} \;

If you happen to have a Unix-like find command on every machine you will ever use,
this is one way to process directories.


Rolling Your Own find Module


But if you don’t happen to have a Unix find on all your computers, not to worry—it’s
easy to code a portable one in Python. Python itself used to have a find module in its
standard library, which I used frequently in the past. Although that module was re-
moved between the second and third editions of this book, the newer os.walk makes
writing your own simple. Rather than lamenting the demise of a module, I decided to
spend 10 minutes coding a custom equivalent.


Example 6-13 implements a find utility in Python, which collects all matching filenames
in a directory tree. Unlike glob.glob, its find.find automatically matches through an
entire tree. And unlike the tree walk structure of os.walk, we can treat find.find results
as a simple linear group.


Example 6-13. PP4E\Tools\find.py


#!/usr/bin/python
"""
################################################################################
Return all files matching a filename pattern at and below a root directory;


custom version of the now deprecated find module in the standard library:
import as "PP4E.Tools.find"; like original, but uses os.walk loop, has no
support for pruning subdirs, and is runnable as a top-level script;


find() is a generator that uses the os.walk() generator to yield just
matching filenames: use findlist() to force results list generation;
################################################################################
"""


import fnmatch, os


def find(pattern, startdir=os.curdir):
for (thisDir, subsHere, filesHere) in os.walk(startdir):
for name in subsHere + filesHere:
if fnmatch.fnmatch(name, pattern):
fullpath = os.path.join(thisDir, name)
yield fullpath


def findlist(pattern, startdir=os.curdir, dosort=False):
matches = list(find(pattern, startdir))
if dosort: matches.sort()
return matches


Searching Directory Trees | 321
Free download pdf