Python中递归删除目录内容时忽略指定模式的实现方法
实现带忽略模式的递归删除目录内容
好问题!确实shutil.rmtree()是用来彻底删除整个目录树的,没有提供类似copytree()那样的ignore参数来跳过特定内容。不过我们可以自己实现这个逻辑,核心思路是遍历目录,选择性删除不匹配忽略模式的内容,甚至可以直接复用shutil.ignore_patterns()来处理模式匹配,不用自己造轮子。
方案一:手动遍历+选择性删除
这个方案最直观,递归遍历目标目录,对每个文件/子目录判断是否需要保留,只删除那些不在忽略列表里的内容。
完整代码实现
import os from shutil import ignore_patterns def rmtree_ignore(source_dir, ignore): """ 递归删除目录下的内容,但忽略符合指定模式的文件/目录 :param source_dir: 要处理的目标目录 :param ignore: 由ignore_patterns()返回的忽略规则函数 """ # 遍历目录下的所有条目 for item in os.listdir(source_dir): item_path = os.path.join(source_dir, item) # 检查当前条目是否在忽略列表中 ignored_items = ignore(source_dir, [item]) if item in ignored_items: continue # 跳过,不删除 # 如果是文件或符号链接,直接删除 if os.path.isfile(item_path) or os.path.islink(item_path): os.unlink(item_path) # 如果是目录,先递归处理子目录内容,再判断是否删除空目录 elif os.path.isdir(item_path): rmtree_ignore(item_path, ignore) # 子目录处理完后如果为空,就删除它 if not os.listdir(item_path): os.rmdir(item_path) # 示例用法:删除source目录下所有内容,除了donotdeletethis.txt if __name__ == "__main__": source = "/path/to/your/source/dir" rmtree_ignore(source, ignore_patterns('donotdeletethis.txt'))
代码说明
- 复用
ignore_patterns():这个函数会帮我们处理通配符匹配(比如*.pyc、tmp*),返回一个可以判断条目是否需要忽略的函数,省去了我们自己写匹配逻辑的麻烦。 - 递归处理子目录:对于每个子目录,先递归删除其内部的非忽略内容,之后如果子目录变成空目录(没有保留任何内容),就把这个空目录也删掉;如果子目录里还有被忽略的内容,就保留该子目录。
- 区分文件和目录:文件/符号链接直接删除,目录则先处理内部再决定是否删除自身。
方案二:临时迁移保留内容(适用于删除整个目录但保留部分内容)
如果你需要的是删除整个目录,但把指定内容保留下来,可以先把要保留的内容移到临时目录,删除原目录后再把保留内容移回去:
import os import shutil from shutil import ignore_patterns def rmtree_with_keep(source_dir, keep_patterns): # 创建临时目录 temp_dir = os.path.join(os.path.dirname(source_dir), f"temp_{os.path.basename(source_dir)}") os.makedirs(temp_dir, exist_ok=True) # 复制要保留的内容到临时目录 shutil.copytree(source_dir, temp_dir, ignore=ignore_patterns(*keep_patterns)) # 删除原目录 shutil.rmtree(source_dir) # 把保留的内容移回原位置 shutil.move(temp_dir, source_dir) # 示例用法:删除整个source目录,但保留donotdeletethis.txt if __name__ == "__main__": source = "/path/to/your/source/dir" rmtree_with_keep(source, ['donotdeletethis.txt'])
注意事项
- 这个方案适合需要彻底替换目录内容,但保留特定文件的场景,但要注意临时目录的权限问题,以及移动过程中可能出现的异常(比如磁盘空间不足)。
- 如果目录很大,复制操作会比较耗时,优先选择方案一。
内容的提问来源于stack exchange,提问作者nezzer
相关产品推荐
相关产品推荐

