Python实战:十分钟搞定设备档案批量整理归档
一、准备工作与环境依赖
在开始编写自动化脚本之前,必须确保你的电脑上已经配置好了Python运行环境,并且安装了处理Excel和文件系统所需的第三方库。本指南基于Python 3.8版本编写,兼容Windows和macOS系统。
1. 安装Python环境
如果尚未安装Python,请访问Python官网下载安装包。安装过程中,务必勾选"Add Python to PATH"选项,这将允许你在命令行中直接运行Python命令。
2. 安装必要依赖库
本脚本需要用到pandas用于读取Excel数据,以及openpyxl用于支持xlsx格式的读写。打开终端(Terminal或CMD),执行以下命令进行安装:
pip install pandas openpyxl
安装成功后,会提示安装的版本号和路径。如果安装速度过慢,建议使用国内镜像源,例如:
pip install pandas openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple
二、数据源与目录结构规范
为了让脚本能够准确无误地工作,我们需要对原始数据和文件目录结构进行标准化定义。请严格按照以下规范在你的电脑上创建文件夹和准备文件。
1. Excel档案清单规范
新建一个Excel文件,命名为device_list.xlsx。该文件必须包含以下三列表头,顺序不限,但列名必须完全一致(区分大小写):
- device_id:设备的唯一编号(如:DEV001)。
- device_name:设备的名称(如:工业离心泵A)。
- category:设备所属分类(如:泵类)。
在Excel中填入实际数据。注意,device_id列不能有空值,且不能有重复值,这是脚本匹配文件的唯一依据。
2. 原始图片文件存放规范
新建一个文件夹,命名为raw_images。将所有需要整理的设备照片、说明书扫描件等放入此文件夹。
关键命名规则:原始文件的文件名中必须包含Excel中的device_id。例如,如果设备ID是DEV001,那么图片文件名可以是DEV001_front.jpg、DEV001-参数.png或DEV001.pdf。脚本会通过检测文件名中是否包含ID来识别归属。
三、核心代码编写与逻辑拆解
在编写完整脚本前,我们先拆解核心逻辑。脚本的主要工作流程是:读取Excel -> 遍历原始文件 -> 匹配ID -> 生成新路径 -> 移动并重命名文件。
1. 读取Excel数据
使用pandas库加载device_list.xlsx。为了防止中文乱码,建议不指定编码或使用默认引擎。读取后,我们将数据转换为字典列表,方便后续通过ID快速查找设备信息。
2. 文件匹配与重命名逻辑
脚本会遍历raw_images文件夹下的每一个文件。对于每一个文件,它会提取文件名,并去Excel数据中查找是否存在包含该ID的记录。
如果找到匹配项:
- 获取该设备的
category和device_name。 - 构建目标文件夹路径:
output/分类/。 - 构建新文件名:
ID_设备名称_原后缀。
如果未找到匹配项:
- 将该文件移动到
output/unknown/文件夹,防止数据丢失。
3. 异常处理与日志输出
为了确保脚本运行稳定,所有的文件操作(移动、创建文件夹)都必须包裹在try-except块中。同时,使用print语句在控制台实时输出每一个文件的处理结果(成功或失败),方便用户排查问题。
四、完整自动化脚本代码
将以下代码完整复制,保存为organize_devices.py文件。请确保该文件与raw_images文件夹和device_list.xlsx文件位于同一级目录下。
```python
import os
import shutil
import pandas as pd
import sys
定义配置常量
EXCEL_FILE = 'device_list.xlsx'
SOURCE_DIR = 'raw_images'
OUTPUT_DIR = 'organized_archives'
UNKNOWN_DIR = os.path.join(OUTPUT_DIR, 'unknown')
def load_device_data():
"""
加载Excel数据并建立索引字典
返回格式: {'DEV001': {'name': '泵A', 'category': '泵类'}, ...}
"""
if not os.path.exists(EXCEL_FILE):
print(f"错误:未找到Excel文件 {EXCEL_FILE}")
sys.exit(1)
try:
df = pd.read_excel(EXCEL_FILE)
检查必要列是否存在
required_cols = ['device_id', 'device_name', 'category']
for col in required_cols:
if col not in df.columns:
print(f"错误:Excel中缺少必要的列:{col}")
sys.exit(1)
将数据转换为字典,以device_id为键
device_map = {}
for index, row in df.iterrows():
d_id = str(row['device_id']).strip()
device_map[d_id] = {
'name': str(row['device_name']).strip(),
'category': str(row['category']).strip()
}
print(f"成功加载Excel数据,共 {len(device_map)} 条设备记录。")
return device_map
except Exception as e:
print(f"读取Excel失败: {e}")
sys.exit(1)
def organize_files(device_map):
"""
遍历源文件夹,匹配ID并移动文件
"""
if not os.path.exists(SOURCE_DIR):
print(f"错误:未找到源文件夹 {SOURCE_DIR}")
sys.exit(1)
创建未知文件存放目录
os.makedirs(UNKNOWN_DIR, exist_ok=True)
count_success = 0
count_unknown = 0
count_error = 0
遍历源文件夹下的所有文件

for filename in os.listdir(SOURCE_DIR):
file_path = os.path.join(SOURCE_DIR, filename)
跳过文件夹,只处理文件
if not os.path.isfile(file_path):
continue
matched_id = None
在文件名中查找是否存在device_id
注意:这里假设ID是连续的字符串,如果ID是数字且包含在长数字中可能会误判
for d_id in device_map.keys():
if d_id in filename:
matched_id = d_id
break
if matched_id:
device_info = device_map[matched_id]
category = device_info['category']
name = device_info['name']
获取文件扩展名
file_ext = os.path.splitext(filename)[1]
构建新文件名:ID_名称.后缀
new_filename = f"{matched_id}_{name}{file_ext}"
构建目标分类目录
target_category_dir = os.path.join(OUTPUT_DIR, category category)
os.makedirs(target_category_dir, exist_ok=True)
target_file_path = os.path.join(target_category_dir, new_filename)
try:
shutil.move(file_path, target_file_path)
print(f"[OK] {filename} -> {category}/{new_filename}")
count_success += 1
except Exception as e:
print(f"[ERR] 移动失败 {filename}: {e}")
count_error += 1
else:
未找到匹配ID,移动到unknown文件夹
try:
shutil.move(file_path, os.path.join(UNKNOWN_DIR, filename))
print(f"[WARN] 未匹配到ID: {filename} -> unknown/")
count_unknown += 1
except Exception as e:
print(f"[ERR] 移动未知文件失败 {filename}: {e}")
count_error += 1
print("-" 30)
print("整理完成!")
print(f"成功归档: {count_success} 个")
print(f"未识别文件: {count_unknown} 个 (已移动至unknown文件夹)")
print(f"操作失败: {count_error} 个")
if __name__ == "__main__":
1. 加载数据
devices = load_device_data()
2. 开始整理
organize_files(devices)
```
五、运行操作与结果验证
代码保存完成后,即可进行执行操作。
1. 执行脚本
在当前文件夹下打开命令行工具。
Windows系统:在文件夹地址栏输入cmd并回车。
Mac/Linux系统:在文件夹右键选择“在终端中打开”。
输入以下命令并回车:
python organize_devices.py
2. 观察控制台输出
脚本运行时,你会看到类似以下的日志滚动:
成功加载Excel数据,共 5 条设备记录。
[OK] DEV001_raw.jpg -> 泵类/DEV001_工业离心泵A.jpg
[OK] DEV002_pic.png -> 阀门类/DEV002_控制阀B.png
[WARN] 未匹配到ID: temp_log.txt -> unknown/
-
整理完成!
成功归档: 2 个
未识别文件: 1 个 (已移动至unknown文件夹)
3. 验证结果
脚本运行结束后,当前目录下会生成一个名为organized_archives的文件夹。打开该文件夹,你应该能看到按照Excel中“分类”列创建的子文件夹。进入子文件夹,文件已被重命名为“ID_设备名称”的格式,且原始文件夹raw_images中对应的文件已被移走(清空或仅保留未被识别的文件)。
六、常见报错处理方案
在实操过程中,可能会遇到一些环境或配置问题,以下是针对常见报错的解决方案。
1. ModuleNotFoundError: No module named 'pandas'
这表示Python环境中没有安装相关库。请重新检查准备工作章节中的安装命令,确保pip指向的是你当前使用的Python环境。如果安装了多个Python版本,建议使用python -m pip install pandas openpyxl进行安装。
2. PermissionError: [Errno 13] Permission denied
这通常是文件权限问题或文件被占用。请检查:
- 目标文件夹是否需要管理员权限才能写入。
- 待移动的图片文件是否正在被其他软件(如Photoshop、Windows照片查看器)打开。请关闭所有预览软件后重试。
3. UnicodeDecodeError 或 编码报错
如果你的Excel文件包含特殊字符或中文路径出现乱码,请确保Excel文件保存为.xlsx格式(现代格式),而不是老旧的.xls格式。如果问题依旧,尝试用Excel打开文件,点击“另存为”,确保编码没有问题。脚本中使用了strip()来处理ID前后的空格,这能有效避免因ID含有不可见空格导致的匹配失败。