» Python创建命令行程序grep » 2. 开发 » 2.9 支持多文件

支持多文件

parser.add_argument('file_paths', nargs='*', default=[], help='File paths to search in')

nargs='*' 允许脚本接受零个或多个(即任意个)文件路径。

意味着可以执行如下操作:

grepy pattern file1.txt file2.txt file3.txt
# 或者
grepy pattern *.txt

注意:
在命令行中直接使用 *.txt 作为参数可能不会一定按你的预期工作,因为通配符模式(如 *.txt)的展开是由 shell(例如 Bash)展开的。 Python 中的 argparse 模块不会自动执行此展开。不过,你可以使用 glob 模块手动展开。

添加多路径版本的 grepgrepy/grep.py:

def grep_m(pattern: Union[str, re.Pattern],
         file_paths: Union[List[str], Literal['']], options: List[str]):
    "grep multiple files"
    if not file_paths:
        return grep(pattern, "", options)
    result = {}
    for file_path in file_paths:
        result.update(grep(pattern, file_path, options))
    return result


def grep_recursive_m(pattern: Union[str, re.Pattern],
         file_paths: Union[List[str], Literal['']], options: List[str]):
    "grep multiple dirs recursively"
    result = {}
    for file_path in file_paths:
        result.update(grep_recursive(pattern, file_path, options))
    return result

修改 argparse 部分,grepy/cli.py:

@@ -1,16 +1,16 @@
 import argparse
 from typing import List, Dict
 
-from grepy.grep import grep, grep_recursive, grep_count, MatchResults
+from grepy.grep import grep_recursive_m, grep_count, grep_m, MatchResults
 
 
 def main():
     parser = argparse.ArgumentParser(description='''
             A grep-like command-line utility from LiteRank,
             see https://literank.cn/project/13/intro''')
     parser.add_argument('pattern', type=str, help='The pattern to search for')
-    parser.add_argument('file_path', type=str, nargs="?", default="",
-                        help='The path to the file to search in')
+    parser.add_argument('file_paths', nargs="*", default=[],
+                        help='File paths to search in')
 
     # Optional arguments
     parser.add_argument('-c', '--count', action='store_true',
@@ -31,11 +31,11 @@ def main():
 
     args = parser.parse_args()
 
-    if args.recursive and args.file_path != "":
-        result = grep_recursive(args.pattern,
-                                args.file_path, get_options(args))
+    if args.recursive and args.file_paths != "":
+        result = grep_recursive_m(args.pattern,
+                                  args.file_paths, get_options(args))
     else:
-        result = grep(args.pattern, args.file_path, get_options(args))
+        result = grep_m(args.pattern, args.file_paths, get_options(args))
 
     if args.count:
         print(grep_count(result))

然后即可执行如下操作:

grepy -n result grepy/*py

# 或者
grepy -n result grepy/cli.py grepy/grep.py

结果:

grepy/cli.py:
35: result = grep_recursive_m(args.pattern,
38: result = grep_m(args.pattern, args.file_paths, get_options(args))
41: print(grep_count(result))
43: print_result(result, args.line_number)
55: def print_result(result: Dict[str, MatchResults], line_number_option: bool):
57: file_count = len(result)
58: for file_path, lines in result.items():

grepy/grep.py:
21: result = {}
23: result.update(grep(pattern, file_path, options))
24: return result
51: def grep_count(result: Dict[str, MatchResults]):
52: return sum([len(v) for v in result.values()])
58: result = {}
60: result.update(grep_recursive(pattern, file_path, options))
61: return result
66: results = {}
70: results.update(grep(pattern, file_path, options))
71: return results

赞👍🏻!顺顺当当!

上页下页