Python中基于文件名多字符串匹配复制指定文件问题
按文件名匹配复制文件问题解决
需求说明
需要将源文件夹中文件名包含指定字符串的文件复制到目标目录,源文件夹文件示例:
20220101(100000-19999).xlsx 20220101(200000-29999).xlsx 20220101(300000-39999).xlsx 20220101(400000-49999).xlsx 20220101(500000-69999).xlsx 20220101(600000-69999).xlsx 20220101(700000-79999).xlsx 20220101(800000-89999).xlsx 20220101(900000-99999).xlsx 20220101(1000000-109999).xlsx 20220101(1100000-119999).xlsx
当指定匹配字符串为"100000"和"500000"时,目标目录需得到:
20220101(100000-19999).xlsx 20220101(500000-69999).xlsx
原代码及报错
尝试的代码:
import shutil import os import glob loc= 'C:/path/to/files/folder' des = 'G:/path/to/files/new_folder' pattern= ["100000", "500000"] patterns= [f"20220101({i}*" for i in pattern] files = Path(loc).rglob(patterns) for file in files: print(file) shutil.copy(file, des )
运行报错:
AttributeError Traceback (most recent call last) Cell In[16], line 10 5 patterns= [f"20220101({i}*" for i in pattern] 8 files = Path(loc).rglob(patterns) ---> 10 for file in files: 11 print(file) 12 shutil.copy(file, des) File ~\anaconda3\lib\pathlib.py:1043, in Path.rglob(self, pattern) 1038 """Recursively yield all existing files (of any kind, including 1039 directories) matching the given relative pattern, anywhere in 1040 this subtree. 1041 """ 1042 sys.audit("pathlib.Path.rglob", self, pattern) -> 1043 drv, root, pattern_parts = self._flavour.parse_parts((pattern,)) 1044 if drv or root: 1045 raise NotImplementedError("Non-relative patterns are unsupported") File ~\anaconda3\lib\pathlib.py:66, in _Flavour.parse_parts(self, parts) 64 continue 65 if altsep: ---> 66 part = part.replace(altsep, sep) 67 drv, root, rel = self.splitroot(part) 68 if sep in rel: AttributeError: 'list' object has no attribute 'replace'
错误原因
Path.rglob()仅接受单个字符串模式,不能传入列表,这是报错的直接原因;- 文件名中的
(是glob模式的特殊字符(用于分组),需要转义才能匹配实际的括号字符。
修正方案
方案1:遍历每个模式执行匹配
针对每个目标字符串生成转义后的glob模式,逐个调用rglob:
import shutil from pathlib import Path loc = 'C:/path/to/files/folder' des = 'G:/path/to/files/new_folder' targets = ["100000", "500000"] # 转义括号,生成每个目标对应的glob模式 patterns = [f"20220101\\({target}*" for target in targets] # 遍历每个模式,匹配文件并复制 for pattern in patterns: for file in Path(loc).rglob(pattern): print(f"复制文件: {file}") shutil.copy(file, des)
方案2:遍历所有文件,检查文件名是否包含目标字符串
如果不需要递归查找,或者更直观匹配,可直接遍历文件并判断:
import shutil from pathlib import Path loc = 'C:/path/to/files/folder' des = 'G:/path/to/files/new_folder' targets = {"100000", "500000"} # 遍历源目录下所有xlsx文件(非递归用iterdir,递归用rglob("*.xlsx")) for file in Path(loc).iterdir(): if file.suffix == ".xlsx" and any(target in file.name for target in targets): print(f"复制文件: {file}") shutil.copy(file, des)
说明
- 方案1适合递归查找子目录中的文件,利用glob模式匹配效率较高;
- 方案2更灵活,可自定义匹配逻辑(比如精确匹配括号内的开头字符串);
- 确保目标目录
des已存在,若不存在可提前用Path(des).mkdir(exist_ok=True)创建。
内容的提问来源于stack exchange,提问作者leslie
相关产品推荐
相关产品推荐

