Python os.walk使用问题:指定目录扫描匹配目标文件
问题:扫描指定目录及子目录查找匹配正则的文件
测试环境
在~/test目录下的结构如下:
[~/test]$ ls NCRAM955E/ RNCMST954E/ RNCMST957E/ test.py*
当前代码
import os, shutil, sys, getopt, re def GetOption(argv): FileDir = "" Roptarget = "" Dirtarget=[] try: opts, args = getopt.getopt(argv, "hD:F:",["FileDir=", "Roptarget="]) except getopt.GetoptError: print ('Error arg input -D <FileDir> -F <Roptarget>') sys.exit(2) for opt, arg in opts: if opt == "-h": print ('Error arg input -D <FileDir> -F <Roptarget>') sys.exit() elif opt in ("-D", "--FileDir"): FileDir = arg Dirtarget = FileDir.split("|") elif opt in ("-F", "--Roptarget"): Roptarget = arg return(Dirtarget, Roptarget) #Below self defined function need update def detect_walk(file_dir): L_0 = [] L = [] DirList,Ropfile = GetOption(sys.argv[1:]) print("DirList = " + str(DirList)) print("Ropfile = " + Ropfile) for root, dirs, files in os.walk(file_dir): for file in files: L_0.append(file) if " ".join(L_0).find(Ropfile): print("target rop file = " + Ropfile) L.append(os.path.join(root, Ropfile)) return(L) if __name__ == '__main__': file_path = "/home/test/" List = detect_walk(file_path)
期望效果
执行命令:
python test.py -D "RNCRAM955E|RNCMST954E" -F "^A20180520.1300+0300-1315+0300*RNCMST954E_statsfile.xml$"
程序仅扫描RNCRAM955E和RNCMST954E目录(包括其子目录),找到匹配给定正则表达式的文件后,输出该文件的完整路径。
改进建议
作为Python新手能写出这样的框架已经很棒了!我帮你梳理下当前代码的问题,再给出具体的改进方案,让它完美实现你想要的功能:
1. 拆分函数职责,避免逻辑混杂
当前detect_walk里又调用参数解析函数,导致函数耦合性太强。应该在主函数里先处理参数,再把参数传给扫描函数,这样每个函数只做一件事,可读性和可维护性更好。
2. 修复正则匹配逻辑,别用字符串包含代替正则
你现在用" ".join(L_0).find(Ropfile)判断匹配,这只是字符串包含检查,完全没用到正则!而且L_0不断追加所有文件名,会越来越大,效率很低。正确做法是用re.fullmatch判断文件名是否完全符合正则规则。
3. 只扫描指定目录,不要固定根路径
当前代码里detect_walk接收的file_dir是固定的/home/test/,但你期望的是扫描-D参数指定的子目录,所以应该遍历DirList里的每个目录,逐个进行os.walk。
4. 增强错误处理,避免运行崩溃
比如检查指定目录是否存在、正则表达式是否合法、必填参数是否齐全,这些细节能让程序更稳定。
5. 优化输出逻辑,清晰展示结果
找到匹配文件后直接打印完整路径,或者收集结果后统一输出,让用户能直观看到找到的文件。
改进后的完整代码
import os import sys import getopt import re def parse_arguments(argv): """解析命令行参数,返回指定目录列表和正则表达式""" target_dirs = [] regex_pattern = "" try: opts, args = getopt.getopt(argv, "hD:F:", ["FileDir=", "Roptarget="]) except getopt.GetoptError: print('用法: python test.py -D <目录1|目录2|...> -F <正则表达式>') print('示例: python test.py -D "RNCRAM955E|RNCMST954E" -F "^A20180520.*RNCMST954E_statsfile.xml$"') sys.exit(2) for opt, arg in opts: if opt == "-h": print('用法: python test.py -D <目录1|目录2|...> -F <正则表达式>') print('示例: python test.py -D "RNCRAM955E|RNCMST954E" -F "^A20180520.*RNCMST954E_statsfile.xml$"') sys.exit() elif opt in ("-D", "--FileDir"): target_dirs = arg.split("|") # 去除目录名前后可能的空格 target_dirs = [dir.strip() for dir in target_dirs] elif opt in ("-F", "--Roptarget"): regex_pattern = arg # 检查必填参数是否齐全 if not target_dirs or not regex_pattern: print('错误: 必须同时指定-D和-F参数') print('用法: python test.py -D <目录1|目录2|...> -F <正则表达式>') sys.exit(2) return target_dirs, regex_pattern def scan_files(target_dirs, regex_pattern): """扫描指定目录,查找匹配正则的文件并返回完整路径列表""" matched_files = [] # 预编译正则表达式,提升匹配效率 try: pattern = re.compile(regex_pattern) except re.error: print(f'错误: 正则表达式"{regex_pattern}"不合法,请检查格式') sys.exit(2) base_path = os.getcwd() # 获取当前工作目录(即~/test) for dir_name in target_dirs: dir_path = os.path.join(base_path, dir_name) # 检查目录是否存在,不存在则跳过并提示 if not os.path.isdir(dir_path): print(f'警告: 目录"{dir_path}"不存在,跳过该目录扫描') continue # 遍历目录及所有子目录 for root, _, files in os.walk(dir_path): for file in files: # 用fullmatch确保整个文件名完全匹配正则规则 if pattern.fullmatch(file): full_path = os.path.join(root, file) matched_files.append(full_path) print(f'找到匹配文件: {full_path}') return matched_files if __name__ == '__main__': target_dirs, regex_pattern = parse_arguments(sys.argv[1:]) scan_files(target_dirs, regex_pattern)
代码说明
- 参数解析:单独用
parse_arguments处理命令行参数,增加了帮助信息、参数校验,用户输入-h就能看到清晰的用法示例。 - 正则处理:预编译正则表达式提升效率,用
re.fullmatch确保文件名完全匹配你写的^...$规则。 - 目录扫描:遍历指定的每个目录,先检查目录是否存在,避免无效扫描;用
os.walk递归遍历子目录,逐个文件匹配。 - 错误处理:增加了正则合法性检查、目录存在性检查、必填参数检查,运行时更稳定,出错时能给出明确提示。
- 输出清晰:找到匹配文件时直接打印完整路径,同时收集结果返回,方便后续扩展功能。
你可以直接运行改进后的代码测试你期望的命令,应该就能得到想要的结果啦!
内容的提问来源于stack exchange,提问作者huang cheng
相关产品推荐
相关产品推荐

