Skip to content

Commit 7461502

Browse files
Add simple recursion and filtering.
1 parent 1bc696b commit 7461502

1 file changed

Lines changed: 38 additions & 5 deletions

File tree

Lib/re/grep.py

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import sys
21
import argparse
3-
import re
42
from collections import deque
3+
import fnmatch
4+
import os
5+
import re
6+
import sys
57

68

79
def find(patterns, line):
@@ -188,6 +190,15 @@ def make_parser():
188190
grp.add_argument('-C', '--context',
189191
type=int, default=0, metavar='NUM',
190192
help='Print NUM lines of output context.')
193+
194+
grp = parser.add_argument_group('File and Directory Selection')
195+
grp.add_argument('-r', '--recursive',
196+
action='store_true',
197+
help='Read all files under each directory, recursively.')
198+
grp.add_argument('--include',
199+
action='append',
200+
metavar='GLOB',
201+
help='Search only files whose base name matches GLOB (using wildcard matching).')
191202
return parser
192203

193204
def parse_args():
@@ -229,13 +240,35 @@ def compile_patterns(opts):
229240
flags = re.IGNORECASE if opts.ignore_case else 0
230241
return [re.compile(pat, flags) for pat in patterns]
231242

243+
def filter_file(opts, filename):
244+
return not opts.include or any(fnmatch.fnmatch(filename, pat)
245+
for pat in opts.include)
246+
247+
def iter_files(opts):
248+
for arg in opts.files or ['-']:
249+
if arg == '-':
250+
yield None
251+
elif os.path.isfile(arg):
252+
if filter_file(opts, os.path.basename(arg)):
253+
yield arg
254+
elif os.path.isdir(arg):
255+
if not opts.recursive:
256+
print(f'error: {arg!r} is a directory', file=sys.stderr)
257+
continue
258+
for dirpath, dirnames, filenames in os.walk(arg):
259+
for filename in filenames:
260+
if filter_file(opts, filename):
261+
yield os.path.join(dirpath, filename)
262+
else:
263+
print(f'error: {arg!r} has unsupported type', file=sys.stderr)
264+
232265
def main():
233266
opts = parse_args()
234267
patterns = compile_patterns(opts)
235268

236269
found = False
237-
for filename in opts.files or ['-']:
238-
if filename == '-':
270+
for filename in iter_files(opts):
271+
if filename is None:
239272
found |= grep(opts, patterns, sys.stdin, opts.label)
240273
else:
241274
with open(filename, encoding=sys.stdin.encoding,
@@ -252,6 +285,6 @@ def main():
252285
except SystemExit:
253286
raise
254287
except BaseException as e:
255-
print(f'error: {e!r}')
288+
print(f'error: {e!r}', file=sys.stderr)
256289
sys.exit(2)
257290
sys.exit(0 if found else 1)

0 commit comments

Comments
 (0)