4人参与 • 2025-04-24 • Dos/bat
想到一个情景。程序实时监测文件夹情况,如果有新文件进入,分析其文件名,然后如果满足预设条件,则做相应操作。比如扫描仪扫描了文件,会将新文件保存进特定文件夹内,可以使用该程序来做处理。
在windows端最直接的就是用.bat批处理,当然使用powershell或者c#、python语言平台更轻松专业,这里使用 .bat 实现。笔者喜欢黑窗口下,看着字符串一行行打印出来的感觉,啊哈哈~~~
使用cmd实现:检测文件夹(d:\projects\cmd\targetdir) 内是否有新文件出现,如果有,查看该文件的文件名,如果是以a字符打头的,那么将该文件发送给远程文件夹(\\desktop-jl8bqnm\temp4share) 程序不断地去检测,注意生成日志方便调式和日后维护。
1. 要想监测文件夹内是否有新文件,需要对比当前的文件列表和之前的文件列表,如果有出入,则有增添删减文件
2. 把新文件名称记录下来,解析字符并做比较,得出满足条件的文件对象。
3. 将满足条件的文件拷贝到远程文件夹中。其中远程通讯需要双方都开启共享。
4. 每个关键操作需要概括为描述性字符,写入日志文件中。
5. 程序需要有死循环机制,让其不断监测,ctrl+c 可退出。
首先必要的变量先定义好:
set "script_dir=%~dp0" %定义当前脚本目录% set "target_dir=d:\projects\cmd\targetdir" %定义监测的目录地址% set "remote_dir=\\desktop-jl8bqnm\temp4share" %定义远程的目录地址% set "log_file=%script_dir%filemonitor.log" %日志文件存放地址% set "check_interval=5" %重新执行的间隔时间 5秒%
之后编写cmd界面,做必要解释:
echo ================================================ echo █ 文件监控传输工具 █ echo ================================================ echo [版本特性] echo √ 严格匹配大写a开头文件 √ 特殊字符支持 echo √ 实时传输状态提示 √ 详细日志记录 echo 监控目录 : "%target_dir%" echo 远程目录 : "%remote_dir%" echo 日志文件 : "%log_file%" echo 检测间隔 : 每%check_interval%秒 echo ================================================ echo [注意] 大文件传输时会暂停监控,保持窗口开启 echo 按 ctrl+c 安全终止程序 echo ================================================
然后,编写核心算法:
:: 生成初始文件快照 dir /b "%target_dir%" > "%script_dir%prevfiles.txt"
再次生成文件快照,和之前的作对比:
dir /b "%target_dir%" > "%script_dir%currentfiles.txt" findstr /v /g:"%script_dir%prevfiles.txt" "%script_dir%currentfiles.txt" > "%script_dir%newfiles.txt"
如果有新增文件,做对应处理:
for /f "usebackq tokens=*" %%f in ("%script_dir%newfiles.txt") do ( call :process_file "%%~f" )
提取文件名首字母:
set "first_char=!filename:~0,1!"
然后做判断,如果符合首字母"a",则做拷贝操作,如果不是忽略文件:
if "!first_char!"=="a" ( color 0a echo 符合条件:大写a开头文件 echo 开始传输,请勿关闭窗口... :: 使用robocopy增强传输(显示进度但保持静默) robocopy "%target_dir%" "%remote_dir%" "!filename!" /njh /njs /ndl /nc /np :: 错误代码处理(robocopy特有代码) if errorlevel 8 ( color 0c echo [严重错误] 代码!errorlevel! 磁盘空间不足 echo [%timestamp%] error: 传输失败 → "!safe_filename!" [代码!errorlevel!] >> "%log_file%" ) else if errorlevel 4 ( color 0e echo [警告] 代码!errorlevel! 文件不匹配 echo [%timestamp%] warn: 传输异常 → "!safe_filename!" [代码!errorlevel!] >> "%log_file%" ) else if errorlevel 1 ( color 0a echo [成功] 传输完成 echo [%timestamp%] success: 已传输 → "!safe_filename!" >> "%log_file%" ) color 0f ) else ( echo 忽略:非大写a开头文件 echo [%timestamp%] info: 忽略文件 → "!safe_filename!" >> "%log_file%" )
因为想要生成日志,因此每做一个操作,获取时间并输入给 .log。
:get_timestamp for /f "tokens=2 delims==." %%t in ('wmic os get localdatetime /value 2^>nul') do set "datetime=%%t" set "timestamp=!datetime:~0,4!-!datetime:~4,2!-!datetime:~6,2! !datetime:~8,2!:!datetime:~10,2!:!datetime:~12,2!"
另外想要不断监测,程序需要循环执行:
rem ... :: ==================== 主监控循环 ===================== :monitor_loop call :get_timestamp rem ... :: 间隔检测(非阻塞等待) timeout /t %check_interval% /nobreak >nul goto monitor_loop
还有一些细节:
使用robocopy命令传输:
robocopy "%target_dir%" "%remote_dir%" "!filename!" /njh /njs /ndl /nc /np /ns /nfl if errorlevel 8 ( ...错误处理... )
更科学更安全,提升特殊字符处理能力,也可以返回错误信息。
robocopy错误代码表:
代码 | 含义 | 处理建议 |
---|---|---|
0 | 无变化 | 正常情况 |
1 | 文件复制成功 | 记录日志 |
4 | 不匹配文件 | 检查文件系统 |
8 | 磁盘空间不足 | 紧急处理 |
16 | 无效参数 | 检查脚本配置 |
因此可以对错误码进行逐一对比操作:
:: 错误代码处理(robocopy特有代码) if errorlevel 8 ( color 0c echo [严重错误] 代码!errorlevel! 磁盘空间不足 echo [%timestamp%] error: 传输失败 → "!safe_filename!" [代码!errorlevel!] >> "%log_file%" ) else if errorlevel 4 ( color 0e echo [警告] 代码!errorlevel! 文件不匹配 echo [%timestamp%] warn: 传输异常 → "!safe_filename!" [代码!errorlevel!] >> "%log_file%" ) else if errorlevel 1 ( color 0a echo [成功] 传输完成 echo [%timestamp%] success: 已传输 → "!safe_filename!" >> "%log_file%" )
还有特殊字符 & 的处理
set "safe_filename=!filename:^&=^^^&!"
避免文件名称有特殊字符。(实际上作为文件名,本身不允许特殊字符,这里做保险之用)
另外:
@echo off
:关闭命令回显,提升界面整洁度
setlocal enabledelayedexpansion
:启用延迟变量扩展,正确处理动态变量,始终在脚本开头使用setlocal
防止污染系统环境变量
title
:自定义控制台窗口标题
color 0f & cls
:设定白色文本并清空内容
还有时刻注意做日志备份信息。如:
echo [%timestamp%] info: 发现文件 → "!safe_filename!" >> "%log_file%"
完整脚本代码如下:
@echo off setlocal enabledelayedexpansion title 文件监控传输工具 v1.4 :: ======================= 配置参数 ======================== set "script_dir=%~dp0" & rem 获取脚本所在目录 set "target_dir=d:\projects\cmd\targetdir" & rem 监控目录 set "remote_dir=\\desktop-jl8bqnm\temp4share" & rem 远程目录 set "log_file=%script_dir%filemonitor.log" & rem 日志文件路径 set "check_interval=5" & rem 检测间隔(秒) :: ====================== 初始化界面 ======================= color 0f & cls echo ================================================ echo █ 文件监控传输工具 █ echo ================================================ echo [版本特性] echo √ 严格匹配大写a开头文件 √ 特殊字符支持 echo √ 实时传输状态提示 √ 详细日志记录 echo 监控目录 : "%target_dir%" echo 远程目录 : "%remote_dir%" echo 日志文件 : "%log_file%" echo 检测间隔 : 每%check_interval%秒 echo ================================================ echo [注意] 大文件传输时会暂停监控,保持窗口开启 echo 按 ctrl+c 安全终止程序 echo ================================================ :: ================== 文件列表初始化 ==================== dir /b "%target_dir%" > "%script_dir%prevfiles.txt" :: ==================== 主监控循环 ===================== :monitor_loop call :get_timestamp echo [%timestamp%] 扫描进行中... :: 生成当前文件列表(安全模式) dir /b "%target_dir%" > "%script_dir%currentfiles.txt" :: 检测新增文件(增强模式) findstr /v /g:"%script_dir%prevfiles.txt" "%script_dir%currentfiles.txt" > "%script_dir%newfiles.txt" :: 处理新增文件(支持特殊字符) for /f "usebackq tokens=*" %%f in ("%script_dir%newfiles.txt") do ( call :process_file "%%~f" ) :: 更新文件列表缓存 move /y "%script_dir%currentfiles.txt" "%script_dir%prevfiles.txt" >nul del "%script_dir%newfiles.txt" 2>nul :: 间隔检测(非阻塞等待) timeout /t %check_interval% /nobreak >nul goto monitor_loop :: ================== 文件处理模块 ===================== :process_file set "filename=%~1" set "safe_filename=!filename:^&=^^^&!" & rem 转义特殊字符 :: 获取首字符(ascii值方式更可靠) set "first_char=!filename:~0,1!" call :get_timestamp :: 日志记录(双重写入) echo [%timestamp%] 发现文件: "!safe_filename!" echo [%timestamp%] info: 发现文件 → "!safe_filename!" >> "%log_file%" :: ============ 严格大写a检测(ascii值65) ============= if "!first_char!"=="a" ( color 0a echo 符合条件:大写a开头文件 echo 开始传输,请勿关闭窗口... :: 使用robocopy增强传输(显示进度但保持静默) robocopy "%target_dir%" "%remote_dir%" "!filename!" /njh /njs /ndl /nc /np :: 错误代码处理(robocopy特有代码) if errorlevel 8 ( color 0c echo [严重错误] 代码!errorlevel! 磁盘空间不足 echo [%timestamp%] error: 传输失败 → "!safe_filename!" [代码!errorlevel!] >> "%log_file%" ) else if errorlevel 4 ( color 0e echo [警告] 代码!errorlevel! 文件不匹配 echo [%timestamp%] warn: 传输异常 → "!safe_filename!" [代码!errorlevel!] >> "%log_file%" ) else if errorlevel 1 ( color 0a echo [成功] 传输完成 echo [%timestamp%] success: 已传输 → "!safe_filename!" >> "%log_file%" ) color 0f ) else ( echo 忽略:非大写a开头文件 echo [%timestamp%] info: 忽略文件 → "!safe_filename!" >> "%log_file%" ) echo -------------------------------------------------------- exit /b :: ================== 时间戳生成模块 ==================== :get_timestamp for /f "tokens=2 delims==." %%t in ('wmic os get localdatetime /value 2^>nul') do set "datetime=%%t" set "timestamp=!datetime:~0,4!-!datetime:~4,2!-!datetime:~6,2! !datetime:~8,2!:!datetime:~10,2!:!datetime:~12,2!" exit /b endlocal
后期还可以优化程序,比如可以引入配置文件----config.ini,如:
[settings] targetdir=d:\projects\cmd\targetdir remotedir=\\desktop-jl8bqnm\temp4share checkinterval=5
还有,对于转义算法,为了处理文件名称带有&
字符:
set "safe_filename=!filename:^&=^^^&!"
!filename:原字符串=新字符串!
表示对变量 filename
进行字符串替换。
原字符串
是 ^&
(实际匹配 &
符号)
新字符串
是 ^^^&
(实际生成转义后的 ^&
)
转义逻辑:
原字符串
中的 ^&
:^
在这里是转义符,表示要匹配实际的 &
符号。
新字符串
中的 ^^^&
:第一个 ^
转义第二个 ^
,生成一个普通 ^
,第三个 ^
转义 &
,生成 ^&
当然该操作仅转义了 &
符号,其他特殊字符如 |
、>
、<
仍需额外处理。
不过正常情况下,文件名称不应该出现特殊字符,所以不用深究。
还有对于:
for /f "usebackq tokens=*" %%f in ("%script_dir%newfiles.txt") do (
为了防止反引号和括号给文本处理带来干扰。
usebackq
参数是为了反引号的正常处理,"%script_dir%newfiles.txt"
,加上双引号,防止括号被解析为命令的一部分,建议所有路径操作强制使用引号包裹,避免解析错误。
还可优化的部分:
1. 临时的prevfiles.txt文件可以不用展现出来,在退出程序前将其消除。
2. 拷贝文件实际上是阻塞程序继续监测的,如果可以,设置成非阻塞的。
3. 设置日志轮转,更科学得管理日志。
该脚本可以作为一个轻量级解决方案案例,展现了实时监控逻辑的实现范式,为复杂系统开发提供了基础设计模式参考。希望给读者一些灵感。cmd,你老爹永远是你老爹~~~~
到此这篇关于批处理脚本(.bat)实现实时监测文件夹并执行命令 [假设有新文件则拷贝到远程文件夹内]的文章就介绍到这了,更多相关批处理.bat实时监测文件夹内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论