【Python】 一键合并所有 .can 文件为单个 CSV 文件

一个简洁实用的 Python 脚本,自动将同目录下所有 .can 文件按文件名排序,合并输出为带时间戳的 CSV 文件,方便代码归档与 Code Review。


目录


1. 需求场景

在 CAPL 项目开发中,测试用例分散在多个 .can 文件中,逐个打开查看效率低下。本脚本一键将这些文件合并为一个 CSV 文件,每个文件内容前自动添加分隔标识,便于:

  • 源码归档与备份
  • 快速全局搜索
  • 传给 ChatGPT/CodeBuddy 做 Code Review
  • 团队成员快速了解项目全貌

2. 脚本功能概览

功能 说明
自动收集 扫描脚本所在目录下所有 .can 文件
按名排序 按文件名升序排列,保证输出顺序稳定
分隔标识 每个文件内容前添加 ====== 文件名 ======
编码兼容 GBK 读取,UTF-8 写入,errors='replace' 容错
时间戳命名 输出文件名自动带时间戳,如 merged_can_20260430_113009.csv

3. 完整源码

import os
import sys
import time
from pathlib import Path

def merge_files_to_txt(input_dir, output_file, extensions=None, recursive=False, encoding='gbk'):
    input_path = Path(input_dir)
    if not input_path.is_dir():
        print(f"错误:输入路径 '{input_dir}' 不是有效的文件夹。")
        return

    # 收集所有匹配的文件(只当前目录,不递归)
    all_files = []
    for file in input_path.iterdir():
        if file.is_file():
            if extensions is None or file.suffix.lower() in extensions:
                all_files.append(file)

    all_files.sort()

    # 写入输出文件
    output_path = Path(output_file)
    output_path.parent.mkdir(parents=True, exist_ok=True)

    with open(output_path, 'w', encoding='utf-8', newline='') as out_f:
        for file_path in all_files:
            out_f.write(f"====== {file_path.name} ======\n")
            try:
                with open(file_path, 'r', encoding=encoding, errors='replace') as in_f:
                    content = in_f.read()
                out_f.write(content)
                if content and not content.endswith('\n'):
                    out_f.write('\n')
            except Exception as e:
                out_f.write(f"[读取文件出错: {e}]\n")
            out_f.write('\n')

    print(f"✅ 合并完成!共 {len(all_files)} 个 .can 文件")
    print(f"📄 输出文件:{output_path}")

def main():
    # ========== 自动配置(无需修改) ==========
    input_directory = os.path.dirname(os.path.abspath(__file__))  # 当前脚本所在文件夹
    timestamp = time.strftime("%Y%m%d_%H%M%S")                   # 时间戳
    output_txt = os.path.join(input_directory, f"merged_can_{timestamp}.csv")

    file_extensions = ['.can']      # 只合并 CAN 文件
    scan_subfolders = False         # 不扫描子文件夹
    read_encoding = 'gbk'           # CAN 中文编码

    merge_files_to_txt(
        input_dir=input_directory,
        output_file=output_txt,
        extensions=file_extensions,
        recursive=scan_subfolders,
        encoding=read_encoding
    )

if __name__ == "__main__":
    main()

4. 代码逐段解析

4.1 导入依赖

import os          # 路径拼接、获取脚本目录
import sys         # 未直接使用,预留
import time        # 生成时间戳
from pathlib import Path  # 面向对象的路径操作

仅依赖 Python 标准库,无需安装第三方包。

4.2 核心合并函数

def merge_files_to_txt(input_dir, output_file, extensions=None, recursive=False, encoding='gbk'):

参数说明

参数 类型 说明
input_dir str 源文件目录
output_file str 输出文件路径
extensions list 指定文件后缀过滤,如 ['.can', '.cin']
recursive bool 是否递归扫描子目录(当前为 False
encoding str 读取文件的编码格式(默认 GBK)

关键步骤

  1. 校验路径 — 检查 input_dir 是否为有效目录
  2. 收集文件 — 遍历目录,按 extensions 过滤,按文件名排序
  3. 逐文件写入 — 写分隔行 → 读源文件内容 → 写入 → 换行
  4. 异常容错errors='replace' 处理编码异常,try/except 捕获读取失败

4.3 主函数自动配置

input_directory = os.path.dirname(os.path.abspath(__file__))
timestamp = time.strftime("%Y%m%d_%H%M%S")
output_txt = os.path.join(input_directory, f"merged_can_{timestamp}.csv")
  • __file__ 获取脚本自身路径,确保在任何位置运行都能正确定位到脚本所在目录
  • time.strftime 生成 YYYYMMDD_HHMMSS 格式时间戳,避免覆盖历史输出

5. 使用方法

merge_files_to_txt_V1.py 放到 .can 文件所在的目录,然后运行:

python merge_files_to_txt_V1.py

执行后会在同目录生成 merged_can_YYYYMMDD_HHMMSS.csv 文件。


6. 输出效果

生成的 CSV 文件格式如下:

====== TG1.can ======
/*@!Encoding:936*/
variables
{
  int TG1_TC1 = 0;
  ...
}

====== FlashCore.can ======
/*@!Encoding:936*/
includes
{
  ...
}

每个源文件内容前都有清晰的分隔标识,方便定位和检索。


7. 可定制扩展

如需合并其他类型文件,只需修改 main() 中的配置:

# 合并 .txt 和 .log 文件
file_extensions = ['.txt', '.log']

# 合并所有文件(不设过滤)
file_extensions = None

# 扫描子目录
scan_subfolders = True

8. 总结

这个脚本共 60 行代码,零第三方依赖,简洁实用。核心价值在于:

  • 开箱即用 — 放到目标目录直接跑
  • 编码兼容好 — GBK → UTF-8 自动处理
  • 输出规范 — 带分隔标识 + 时间戳,方便追溯

非常适合作为日常开发中的"随手工具"。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐