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

(yzsuai) #1

changes. There are a variety of solutions to such goals—from shell commands, to find
operations, to custom tree walkers, to general-purpose frameworks. In this and the next
section, we’ll explore each option in turn, just as I did while refining solutions to this
real-world dilemma.


Greps and Globs and Finds


If you work on Unix-like systems, you probably already know that there is a standard
way to search files for strings on such platforms—the command-line program grep and
its relatives list all lines in one or more files containing a string or string pattern.‖ Given
that shells expand (i.e., “glob”) filename patterns automatically, a command such as
the following will search a single directory’s Python files for a string named on the
command line (this uses the grep command installed with the Cygwin Unix-like system
for Windows that I described in the prior chapter):


C:\...\PP4E\System\Filetools> c:\cygwin\bin\grep.exe walk *.py
bigext-tree.py:for (thisDir, subsHere, filesHere) in os.walk(dirname):
bigpy-path.py: for (thisDir, subsHere, filesHere) in os.walk(srcdir):
bigpy-tree.py:for (thisDir, subsHere, filesHere) in os.walk(dirname):

As we’ve seen, we can often accomplish the same within a Python script by running
such a shell command with os.system or os.popen. And if we search its results manually,
we can also achieve similar results with the Python glob module we met in Chapter 4;
it expands a filename pattern into a list of matching filename strings much like a shell:


C:\...\PP4E\System\Filetools> python
>>> import os
>>> for line in os.popen(r'c:\cygwin\bin\grep.exe walk *.py'):
... print(line, end='')
...
bigext-tree.py:for (thisDir, subsHere, filesHere) in os.walk(dirname):
bigpy-path.py: for (thisDir, subsHere, filesHere) in os.walk(srcdir):
bigpy-tree.py:for (thisDir, subsHere, filesHere) in os.walk(dirname):

>>> from glob import glob
>>> for filename in glob('*.py'):
... if 'walk' in open(filename).read():
... print(filename)
...
bigext-tree.py
bigpy-path.py
bigpy-tree.py

Unfortunately, these tools are generally limited to a single directory. glob can visit
multiple directories given the right sort of pattern string, but it’s not a general directory
walker of the sort I need to maintain a large examples tree. On Unix-like systems, a
find shell command can go the extra mile to traverse an entire directory tree. For


‖In fact, the act of searching files often goes by the colloquial name “grepping” among developers who have
spent any substantial time in the Unix ghetto.


320 | Chapter 6: Complete System Programs

Free download pdf