修改批处理脚本:按指定总大小批量处理CSV文件并完成打包、聚合与清单生成
修改批处理脚本:按指定总大小批量处理CSV文件并完成打包、聚合与清单生成
我明白你现在的核心需求是把原来按固定数量选文件的逻辑,改成按指定总文件大小来批量选取源文件(包含对应的flag文件),同时保留后续的CSV聚合、清单生成、RAR打包这些流程。下面是修改后的完整批处理脚本,我会逐段解释关键改动,方便你理解和调整:
完整修改后的脚本
@echo off && setlocal enabledelayedexpansion :: 配置参数 - 可根据实际需求修改 set "_source_folder=D:\source" set "_target_folder=D:\target" set "_temp_folder=D:\temp" set "_max_total_size_mb=200" :: 每个包的目标总大小(MB) set "_min_remaining_size_percent=50" :: 剩余文件大小低于此百分比时,直接打包剩余所有 :: 将MB转换为字节(用于文件大小计算) set /a "_max_total_size_bytes=%_max_total_size_mb%*1024*1024" set /a "_min_remaining_size_bytes=%_max_total_size_bytes%*%_min_remaining_size_percent%/100" :: 创建必要的目录(如果不存在) if not exist "%_source_folder%" mkdir "%_source_folder%" if not exist "%_target_folder%" mkdir "%_target_folder%" if not exist "%_temp_folder%" mkdir "%_temp_folder%" :PROCESS_LOOP :: 初始化当前包的统计变量 set "_current_total_size=0" set "_file_count=0" :: 查找下一个可用的包编号 set "_pack=01" for /f "delims=" %%f in ('dir /b /o:n "%_target_folder%\Pack_*.csv" 2^>nul') do ( set "filename=%%f" set "pack_num=!filename:~5,2!" if !pack_num! gtr !_pack! set "_pack=!pack_num!" ) set /a "_pack+=1" :: 格式化包编号为两位数字(比如1变成01,10保持10) if !_pack! lss 10 set "_pack=0!_pack!" :: =============================================================================== REM TASK 1 - 按指定总大小选取源文件(主文件+对应flag文件) REM =============================================================================== echo 正在收集文件,目标总大小:%_max_total_size_mb%MB... :: 遍历源文件夹中的主CSV文件(按文件大小从小到大,优先选小文件凑满大小) for /f "delims=" %%a in ('dir /a-d /o:s /b "%_source_folder%\*source-file.csv"') do ( :: 获取主文件名(不含后缀) set "main_file=%%a" set "main_name=%%~na" :: 构建对应的flag文件名 set "flag_file=!main_name!-flag.csv" :: 检查flag文件是否存在 if not exist "%_source_folder%\!flag_file!" ( echo 警告:主文件 %%a 对应的flag文件 !flag_file! 不存在,跳过此文件 goto :NEXT_MAIN_FILE ) :: 计算当前主文件+flag文件的总大小 set /a "file_pair_size=%%~za + %%~z%_source_folder%\!flag_file!" :: 判断累加后是否超过最大限制 set /a "new_total=!_current_total_size! + !file_pair_size!" if !new_total! gtr !_max_total_size_bytes! ( :: 检查剩余文件总大小是否低于阈值,如果是则继续打包 set "remaining_total=0" for /f "delims=" %%r in ('dir /a-d /b "%_source_folder%\*source-file.csv"') do ( set "r_main=%%r" set "r_flag=%%~nr-flag.csv" if exist "%_source_folder%\!r_flag!" set /a "remaining_total+=%%~zr + %%~z%_source_folder%\!r_flag!" ) if !remaining_total! leq !_min_remaining_size_bytes! ( echo 剩余文件总大小低于阈值,将剩余所有文件加入当前包 ) else ( echo 当前累加已达大小限制,停止收集文件 goto :END_FILE_COLLECTION ) ) :: 移动主文件和flag文件到临时文件夹 move /y "%_source_folder%\!main_file!" "%_temp_folder%\" >nul move /y "%_source_folder%\!flag_file!" "%_temp_folder%\" >nul echo 已添加:!main_file! + !flag_file! set "_current_total_size=!new_total!" set /a "_file_count+=1" :NEXT_MAIN_FILE ) :END_FILE_COLLECTION :: 检查是否收集到了文件 if !_file_count! equ 0 ( echo 源文件夹已无文件可处理,脚本结束 goto :CLEANUP_EXIT ) :: 转换当前总大小为MB,方便输出 set /a "_current_total_mb=!_current_total_size!/1024/1024" echo 本次收集完成:共!_file_count!对文件,总大小约!_current_total_mb!MB :: =============================================================================== REM TASK 2 - 创建聚合后的CSV文件(仅包含主文件数据,保留表头) REM =============================================================================== echo 正在生成聚合CSV文件 Pack_%_pack%.csv... :: 第一步:复制所有主文件到临时聚合文件(包含所有表头) copy "%_temp_folder%\*source-file.csv" "%_temp_folder%\temp_0.csv" /b >nul :: 第二步:生成带正确表头的最终聚合文件 >"%_target_folder%\Pack_%_pack%.csv" echo.Date,Time :: 第三步:过滤掉临时文件中的重复表头,只保留数据行 >"%_temp_folder%\temp_1.csv" findstr /v "Column1,Column2" "%_temp_folder%\temp_0.csv" :: 第四步:将数据行追加到最终聚合文件 >>"%_target_folder%\Pack_%_pack%.csv" type "%_temp_folder%\temp_1.csv" :: =============================================================================== REM TASK 3 - 创建打包文件清单(仅包含主文件名) REM =============================================================================== echo 正在生成文件清单 Pack_%_pack%_LIST.txt... >"%_target_folder%\Pack_%_pack%_LIST.txt" ( for /f "delims=" %%a in ('dir /a-d /b "%_temp_folder%\*source-file.csv"') do ( echo %%~na ) ) :: =============================================================================== REM TASK 4 - 创建RAR压缩包(包含主文件+flag文件) REM =============================================================================== echo 正在创建RAR压缩包 Pack_%_pack%.rar... "C:\Program Files\WinRAR\winrar.exe" a -ep1 -r "%_target_folder%\Pack_%_pack%.rar" "%_temp_folder%\*source-file*.csv" >nul :: =============================================================================== REM TASK 5 - 清理临时文件夹 REM =============================================================================== echo 正在清理临时文件... del /q /a "%_temp_folder%\*.*" :: 检查源文件夹是否还有剩余文件,如果有则继续循环处理 dir /b "%_source_folder%\*source-file.csv" >nul 2>&1 if not errorlevel 1 goto :PROCESS_LOOP :CLEANUP_EXIT echo 所有文件处理完成! endlocal pause exit /b
关键改动说明
可自定义的参数配置
- 新增了
_max_total_size_mb(每个包的目标总大小,默认200MB)和_min_remaining_size_percent(剩余文件阈值,默认50%),你可以根据实际需求直接修改这些值 - 自动将MB转换为字节单位,适配Windows批处理的文件大小计算逻辑
- 新增了
自动递增包编号
- 不再固定使用
01作为包编号,脚本会自动查找目标文件夹中已有的最大包编号,每次处理自动加1,彻底避免覆盖旧文件的问题
- 不再固定使用
按大小选文件的核心逻辑
- 按文件大小从小到大遍历主文件,优先用小文件凑满目标大小,避免单个超大文件无法打包的情况
- 每次选取一对主文件+flag文件,计算两者的总大小后判断是否超过阈值
- 加入了剩余文件判断:如果剩余文件总大小低于目标大小的50%,就直接打包剩余所有文件,不会残留少量文件在源文件夹
完善的异常处理
- 每次选取主文件时,会检查对应的flag文件是否存在,不存在则跳过该主文件,避免脚本出错中断
- 处理过程中添加了清晰的提示信息,你可以实时看到每一步的进展
优化的RAR打包参数
- 新增了
-ep1参数,压缩时会去掉临时文件夹的路径,让压缩包内的文件结构更简洁
- 新增了
备注:内容来源于stack exchange,提问作者jt99
相关产品推荐
相关产品推荐

