
本文介绍一种简洁高效的方法,通过截取固定长度的日期时间前缀来提取文件名核心部分,识别并删除重复项,仅保留每个唯一名称的一个实例。
本文介绍一种简洁高效的方法,通过截取固定长度的日期时间前缀来提取文件名核心部分,识别并删除重复项,仅保留每个唯一名称的一个实例。
在实际文件管理中,常遇到按时间戳命名但内容相同的重复文件(如日志、导出报告等),例如:
2024-11-22 23-40-25 - Konstrukteur - Möbel (mwd).txt 2024-11-22 22-14-02 - Konstrukteur - Möbel (mwd).txt 2024-11-22 22-02-34 - Konstrukteur - Möbel (mwd).txt 2024-11-22 22-01-58 - Konstrukteur - Möbel (mwd).txt
这些文件的前19个字符(YYYY-MM-DD HH-MM-SS,含空格和连字符,共19位)为可变的时间戳,其后内容完全一致。因此,无需正则表达式——只需统一切片即可精准提取“语义主干”。
以下是推荐的健壮实现方案:
import os
def deduplicate_by_basename(file_list, keep_first=True):
"""
删除重复文件:基于去除固定宽度时间戳后的文件名主体进行去重。
默认保留首次出现的文件,删除后续重复项。
:param file_list: 文件路径列表(支持相对/绝对路径)
:param keep_first: True → 保留第一个;False → 保留最后一个(需调整逻辑)
"""
seen = set()
removed_count = 0
for file_path in file_list:
# 确保文件存在且为普通文件
if not os.path.isfile(file_path):
continue
# 提取核心名称:跳过前19字符("YYYY-MM-DD HH-MM-SS "格式)
try:
core_name = file_path[19:]
except IndexError:
print(f"Warning: filename too short, skipped: {file_path}")
continue
if core_name in seen:
try:
os.remove(file_path)
print(f"✓ Deleted: {file_path}")
removed_count += 1
except OSError as e:
print(f"✗ Failed to delete {file_path}: {e}")
else:
seen.add(core_name)
print(f"Total duplicates removed: {removed_count}")
# 使用示例
files = [
"2024-11-22 23-40-25 - Konstrukteur - Möbel (mwd).txt",
"2024-11-22 22-14-02 - Konstrukteur - Möbel (mwd).txt",
"2024-11-22 22-02-34 - Konstrukteur - Möbel (mwd).txt",
"2024-11-22 22-01-58 - Konstrukteur - Möbel (mwd).txt"
]
deduplicate_by_basename(files)✅ 关键优势:
- 零依赖、零正则,性能高且可读性强;
- 利用已知命名规范(固定宽度时间戳),比正则更稳定;
- 内置错误处理(跳过非法路径、捕获删除异常);
- 支持任意路径(含目录),不局限于当前工作目录。
⚠️ 注意事项:
- 此方法严格依赖时间戳为 19 字符固定格式(YYYY-MM-DD HH-MM-SS,注意末尾空格)。若存在不同格式(如无空格、秒数缺失、毫秒等),需先统一预处理或改用正则 r'\d{4}-\d{2}-\d{2} \d{2}-\d{2}-\d{2} - (.+)' 提取主体;
- 操作前建议先备份或使用 print() 替代 os.remove() 进行 dry-run 验证;
- 若需保留最新文件(而非第一个),可先按修改时间排序再执行去重。
该方案兼顾简洁性与生产可用性,是处理此类结构化命名重复文件的理想实践。

















