遍历目录重命名文件时二次运行大量文件丢失,原因是什么?
问题原因
第二次运行代码时,os.listdir()会把目录里所有文件都列出来,包括第一次运行后生成的1.svg、2.svg这类已重命名的文件。遍历过程中,这些已命名的文件会被再次分配新的序号,导致文件被覆盖或重复改名,最终大量文件丢失。
比如第一次运行后目录有1.svg、2.svg、原文件A.svg,第二次运行时lst包含这三个文件,遍历到1.svg时,counter是1,会把1.svg重命名为1.svg(等于没改),但如果counter走到3,刚好要把原文件A.svg改成3.svg,但如果之前某个已命名文件被改成了3.svg,就会直接覆盖,导致原文件丢失。
解决办法
方法1:只处理非序号命名的文件
在遍历前先过滤掉已经是数字.svg格式的文件,确保只处理未被重命名的原文件:
import os import re pth = "path here" # 匹配纯数字命名的.svg文件 pattern = re.compile(r'^\d+\.svg$') # 过滤出不符合该格式的文件,只处理原文件 lst = [fle for fle in os.listdir(pth) if not pattern.match(fle)] counter = 1 for fle in lst: new_pth = os.path.join(pth, fle) # 用os.path.join避免路径拼接错误 final_pth = os.path.join(pth, str(counter) + ".svg") os.rename(new_pth, final_pth) counter += 1
方法2:根据原文件特征过滤
如果原文件有统一的后缀(比如不是.svg,或者有特定前缀),可以直接过滤:
import os pth = "path here" # 假设原文件都是.png格式,只处理这些文件 lst = [fle for fle in os.listdir(pth) if fle.endswith(".png")] counter = 1 for fle in lst: new_pth = os.path.join(pth, fle) final_pth = os.path.join(pth, str(counter) + ".svg") os.rename(new_pth, final_pth) counter += 1
方法3:先获取最大序号,从下一个序号开始命名
如果需要保留已有的序号文件,在新文件后面继续编号:
import os import re pth = "path here" # 找出所有已存在的数字.svg文件,获取最大序号 max_num = 0 pattern = re.compile(r'^(\d+)\.svg$') for fle in os.listdir(pth): match = pattern.match(fle) if match: num = int(match.group(1)) if num > max_num: max_num = num # 过滤出需要重命名的文件(这里假设原文件不是数字.svg) lst = [fle for fle in os.listdir(pth) if not pattern.match(fle)] counter = max_num + 1 for fle in lst: new_pth = os.path.join(pth, fle) final_pth = os.path.join(pth, str(counter) + ".svg") os.rename(new_pth, final_pth) counter += 1
另外,建议用os.path.join()拼接路径,避免因为系统路径分隔符(Windows是\,Linux是/)导致的错误。
内容的提问来源于stack exchange,提问作者i_feel_dumb
相关产品推荐
相关产品推荐

