批處理腳本(.bat)實(shí)現(xiàn)實(shí)時(shí)監(jiān)測(cè)文件夾并執(zhí)行命令?(假設(shè)有新文件則拷貝到遠(yuǎn)程文件夾內(nèi))
想到一個(gè)情景。程序?qū)崟r(shí)監(jiān)測(cè)文件夾情況,如果有新文件進(jìn)入,分析其文件名,然后如果滿(mǎn)足預(yù)設(shè)條件,則做相應(yīng)操作。比如掃描儀掃描了文件,會(huì)將新文件保存進(jìn)特定文件夾內(nèi),可以使用該程序來(lái)做處理。
在Windows端最直接的就是用.bat批處理,當(dāng)然使用Powershell或者C#、python語(yǔ)言平臺(tái)更輕松專(zhuān)業(yè),這里使用 .bat 實(shí)現(xiàn)。筆者喜歡黑窗口下,看著字符串一行行打印出來(lái)的感覺(jué),啊哈哈~~~
【設(shè)計(jì)需求】
使用cmd實(shí)現(xiàn):檢測(cè)文件夾(D:\projects\cmd\targetdir) 內(nèi)是否有新文件出現(xiàn),如果有,查看該文件的文件名,如果是以A字符打頭的,那么將該文件發(fā)送給遠(yuǎn)程文件夾(\\DESKTOP-JL8BQNM\temp4share) 程序不斷地去檢測(cè),注意生成日志方便調(diào)式和日后維護(hù)。
【設(shè)計(jì)思路】
1. 要想監(jiān)測(cè)文件夾內(nèi)是否有新文件,需要對(duì)比當(dāng)前的文件列表和之前的文件列表,如果有出入,則有增添刪減文件
2. 把新文件名稱(chēng)記錄下來(lái),解析字符并做比較,得出滿(mǎn)足條件的文件對(duì)象。
3. 將滿(mǎn)足條件的文件拷貝到遠(yuǎn)程文件夾中。其中遠(yuǎn)程通訊需要雙方都開(kāi)啟共享。
4. 每個(gè)關(guān)鍵操作需要概括為描述性字符,寫(xiě)入日志文件中。
5. 程序需要有死循環(huán)機(jī)制,讓其不斷監(jiān)測(cè),Ctrl+C 可退出。
【設(shè)計(jì)腳本】
首先必要的變量先定義好:
set "script_dir=%~dp0" %定義當(dāng)前腳本目錄% set "target_dir=D:\projects\cmd\targetdir" %定義監(jiān)測(cè)的目錄地址% set "remote_dir=\\DESKTOP-JL8BQNM\temp4share" %定義遠(yuǎn)程的目錄地址% set "log_file=%script_dir%FileMonitor.log" %日志文件存放地址% set "check_interval=5" %重新執(zhí)行的間隔時(shí)間 5秒%
之后編寫(xiě)cmd界面,做必要解釋?zhuān)?/p>
echo ================================================ echo █ 文件監(jiān)控傳輸工具 █ echo ================================================ echo [版本特性] echo √ 嚴(yán)格匹配大寫(xiě)A開(kāi)頭文件 √ 特殊字符支持 echo √ 實(shí)時(shí)傳輸狀態(tài)提示 √ 詳細(xì)日志記錄 echo 監(jiān)控目錄 : "%target_dir%" echo 遠(yuǎn)程目錄 : "%remote_dir%" echo 日志文件 : "%log_file%" echo 檢測(cè)間隔 : 每%check_interval%秒 echo ================================================ echo [注意] 大文件傳輸時(shí)會(huì)暫停監(jiān)控,保持窗口開(kāi)啟 echo 按 Ctrl+C 安全終止程序 echo ================================================
然后,編寫(xiě)核心算法:
:: 生成初始文件快照 dir /b "%target_dir%" > "%script_dir%prevfiles.txt"
再次生成文件快照,和之前的作對(duì)比:
dir /b "%target_dir%" > "%script_dir%currentfiles.txt" findstr /v /g:"%script_dir%prevfiles.txt" "%script_dir%currentfiles.txt" > "%script_dir%newfiles.txt"
如果有新增文件,做對(duì)應(yīng)處理:
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 符合條件:大寫(xiě)A開(kāi)頭文件 echo 開(kāi)始傳輸,請(qǐng)勿關(guān)閉窗口... :: 使用robocopy增強(qiáng)傳輸(顯示進(jìn)度但保持靜默) robocopy "%target_dir%" "%remote_dir%" "!filename!" /njh /njs /ndl /nc /np :: 錯(cuò)誤代碼處理(ROBOCOPY特有代碼) if errorlevel 8 ( color 0C echo [嚴(yán)重錯(cuò)誤] 代碼!errorlevel! 磁盤(pán)空間不足 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 忽略:非大寫(xiě)A開(kāi)頭文件 echo [%timestamp%] INFO: 忽略文件 → "!safe_filename!" >> "%log_file%" )
因?yàn)橄胍扇罩?,因此每做一個(gè)操作,獲取時(shí)間并輸入給 .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!"
另外想要不斷監(jiān)測(cè),程序需要循環(huán)執(zhí)行:
rem ... :: ==================== 主監(jiān)控循環(huán) ===================== :monitor_loop call :get_timestamp rem ... :: 間隔檢測(cè)(非阻塞等待) timeout /t %check_interval% /nobreak >nul goto monitor_loop
還有一些細(xì)節(jié):
使用robocopy命令傳輸:
robocopy "%target_dir%" "%remote_dir%" "!filename!" /njh /njs /ndl /nc /np /ns /nfl if errorlevel 8 ( ...錯(cuò)誤處理... )
更科學(xué)更安全,提升特殊字符處理能力,也可以返回錯(cuò)誤信息。
ROBOCOPY錯(cuò)誤代碼表:
代碼 | 含義 | 處理建議 |
---|---|---|
0 | 無(wú)變化 | 正常情況 |
1 | 文件復(fù)制成功 | 記錄日志 |
4 | 不匹配文件 | 檢查文件系統(tǒng) |
8 | 磁盤(pán)空間不足 | 緊急處理 |
16 | 無(wú)效參數(shù) | 檢查腳本配置 |
因此可以對(duì)錯(cuò)誤碼進(jìn)行逐一對(duì)比操作:
:: 錯(cuò)誤代碼處理(ROBOCOPY特有代碼) if errorlevel 8 ( color 0C echo [嚴(yán)重錯(cuò)誤] 代碼!errorlevel! 磁盤(pán)空間不足 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:^&=^^^&!"
避免文件名稱(chēng)有特殊字符。(實(shí)際上作為文件名,本身不允許特殊字符,這里做保險(xiǎn)之用)
另外:
@echo off
:關(guān)閉命令回顯,提升界面整潔度
setlocal enabledelayedexpansion
:?jiǎn)⒂醚舆t變量擴(kuò)展,正確處理動(dòng)態(tài)變量,始終在腳本開(kāi)頭使用setlocal
防止污染系統(tǒng)環(huán)境變量
title
:自定義控制臺(tái)窗口標(biāo)題
color 0F & cls
:設(shè)定白色文本并清空內(nèi)容
還有時(shí)刻注意做日志備份信息。如:
echo [%timestamp%] INFO: 發(fā)現(xiàn)文件 → "!safe_filename!" >> "%log_file%"
完整腳本代碼如下:
@echo off setlocal enabledelayedexpansion title 文件監(jiān)控傳輸工具 V1.4 :: ======================= 配置參數(shù) ======================== set "script_dir=%~dp0" & rem 獲取腳本所在目錄 set "target_dir=D:\projects\cmd\targetdir" & rem 監(jiān)控目錄 set "remote_dir=\\DESKTOP-JL8BQNM\temp4share" & rem 遠(yuǎn)程目錄 set "log_file=%script_dir%FileMonitor.log" & rem 日志文件路徑 set "check_interval=5" & rem 檢測(cè)間隔(秒) :: ====================== 初始化界面 ======================= color 0F & cls echo ================================================ echo █ 文件監(jiān)控傳輸工具 █ echo ================================================ echo [版本特性] echo √ 嚴(yán)格匹配大寫(xiě)A開(kāi)頭文件 √ 特殊字符支持 echo √ 實(shí)時(shí)傳輸狀態(tài)提示 √ 詳細(xì)日志記錄 echo 監(jiān)控目錄 : "%target_dir%" echo 遠(yuǎn)程目錄 : "%remote_dir%" echo 日志文件 : "%log_file%" echo 檢測(cè)間隔 : 每%check_interval%秒 echo ================================================ echo [注意] 大文件傳輸時(shí)會(huì)暫停監(jiān)控,保持窗口開(kāi)啟 echo 按 Ctrl+C 安全終止程序 echo ================================================ :: ================== 文件列表初始化 ==================== dir /b "%target_dir%" > "%script_dir%prevfiles.txt" :: ==================== 主監(jiān)控循環(huán) ===================== :monitor_loop call :get_timestamp echo [%timestamp%] 掃描進(jìn)行中... :: 生成當(dāng)前文件列表(安全模式) dir /b "%target_dir%" > "%script_dir%currentfiles.txt" :: 檢測(cè)新增文件(增強(qiáng)模式) 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 :: 間隔檢測(cè)(非阻塞等待) timeout /t %check_interval% /nobreak >nul goto monitor_loop :: ================== 文件處理模塊 ===================== :process_file set "filename=%~1" set "safe_filename=!filename:^&=^^^&!" & rem 轉(zhuǎn)義特殊字符 :: 獲取首字符(ASCII值方式更可靠) set "first_char=!filename:~0,1!" call :get_timestamp :: 日志記錄(雙重寫(xiě)入) echo [%timestamp%] 發(fā)現(xiàn)文件: "!safe_filename!" echo [%timestamp%] INFO: 發(fā)現(xiàn)文件 → "!safe_filename!" >> "%log_file%" :: ============ 嚴(yán)格大寫(xiě)A檢測(cè)(ASCII值65) ============= if "!first_char!"=="A" ( color 0A echo 符合條件:大寫(xiě)A開(kāi)頭文件 echo 開(kāi)始傳輸,請(qǐng)勿關(guān)閉窗口... :: 使用robocopy增強(qiáng)傳輸(顯示進(jìn)度但保持靜默) robocopy "%target_dir%" "%remote_dir%" "!filename!" /njh /njs /ndl /nc /np :: 錯(cuò)誤代碼處理(ROBOCOPY特有代碼) if errorlevel 8 ( color 0C echo [嚴(yán)重錯(cuò)誤] 代碼!errorlevel! 磁盤(pán)空間不足 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 忽略:非大寫(xiě)A開(kāi)頭文件 echo [%timestamp%] INFO: 忽略文件 → "!safe_filename!" >> "%log_file%" ) echo -------------------------------------------------------- exit /b :: ================== 時(shí)間戳生成模塊 ==================== :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
【設(shè)計(jì)小結(jié)】
后期還可以?xún)?yōu)化程序,比如可以引入配置文件----config.ini,如:
[Settings] TargetDir=D:\projects\cmd\targetdir RemoteDir=\\DESKTOP-JL8BQNM\temp4share CheckInterval=5
還有,對(duì)于轉(zhuǎn)義算法,為了處理文件名稱(chēng)帶有&
字符:
set "safe_filename=!filename:^&=^^^&!"
!filename:原字符串=新字符串!
表示對(duì)變量 filename
進(jìn)行字符串替換。
原字符串
是 ^&
(實(shí)際匹配 &
符號(hào))
新字符串
是 ^^^&
(實(shí)際生成轉(zhuǎn)義后的 ^&
)
轉(zhuǎn)義邏輯:
原字符串
中的 ^&
:^
在這里是轉(zhuǎn)義符,表示要匹配實(shí)際的 &
符號(hào)。
新字符串
中的 ^^^&
:第一個(gè) ^
轉(zhuǎn)義第二個(gè) ^
,生成一個(gè)普通 ^
,第三個(gè) ^
轉(zhuǎn)義 &
,生成 ^&
當(dāng)然該操作僅轉(zhuǎn)義了 &
符號(hào),其他特殊字符如 |
、>
、<
仍需額外處理。
不過(guò)正常情況下,文件名稱(chēng)不應(yīng)該出現(xiàn)特殊字符,所以不用深究。
還有對(duì)于:
for /f "usebackq tokens=*" %%f in ("%script_dir%newfiles.txt") do (
為了防止反引號(hào)和括號(hào)給文本處理帶來(lái)干擾。
usebackq
參數(shù)是為了反引號(hào)的正常處理,"%script_dir%newfiles.txt"
,加上雙引號(hào),防止括號(hào)被解析為命令的一部分,建議所有路徑操作強(qiáng)制使用引號(hào)包裹,避免解析錯(cuò)誤。
還可優(yōu)化的部分:
1. 臨時(shí)的prevfiles.txt文件可以不用展現(xiàn)出來(lái),在退出程序前將其消除。
2. 拷貝文件實(shí)際上是阻塞程序繼續(xù)監(jiān)測(cè)的,如果可以,設(shè)置成非阻塞的。
3. 設(shè)置日志輪轉(zhuǎn),更科學(xué)得管理日志。
【設(shè)計(jì)展示】
該腳本可以作為一個(gè)輕量級(jí)解決方案案例,展現(xiàn)了實(shí)時(shí)監(jiān)控邏輯的實(shí)現(xiàn)范式,為復(fù)雜系統(tǒng)開(kāi)發(fā)提供了基礎(chǔ)設(shè)計(jì)模式參考。希望給讀者一些靈感。CMD,你老爹永遠(yuǎn)是你老爹~~~~
到此這篇關(guān)于批處理腳本(.bat)實(shí)現(xiàn)實(shí)時(shí)監(jiān)測(cè)文件夾并執(zhí)行命令 [假設(shè)有新文件則拷貝到遠(yuǎn)程文件夾內(nèi)]的文章就介紹到這了,更多相關(guān)批處理.bat實(shí)時(shí)監(jiān)測(cè)文件夾內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用 windows bat 腳本命令一鍵啟動(dòng)MySQL服務(wù)的方法
這篇文章主要介紹了使用 windows bat 腳本命令 一鍵啟動(dòng)MySQL服務(wù)的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10批處理實(shí)現(xiàn)ping數(shù)據(jù)中文版
將ping返回的數(shù)據(jù),中文化輸出。2009-06-06windows服務(wù)操作之刪除服務(wù) 批處理實(shí)現(xiàn)
用批處理實(shí)現(xiàn)的刪除服務(wù)器的方法,其實(shí)就是利用了批處理下的sc命令。2009-03-03bat文件加密 bat解密腳本(讓bat亂碼現(xiàn)形)
很多朋友想把自己寫(xiě)的bat加密,防止別人隨意修改,但也有人想將別人加密的bat解密,查看源碼學(xué)習(xí)等,本來(lái)就是一個(gè)矛盾體,這里腳本之家都給整理下方便需要的朋友2013-01-01win2003下殺任何進(jìn)程的命令(taskkill,ntsd)
才能關(guān)掉一個(gè)用任務(wù)管理器關(guān)不了的進(jìn)程?大多數(shù)人想到的都是專(zhuān)門(mén)工具,如IceSword。其實(shí)用Windows自帶的工具就能殺大部分進(jìn)程2011-10-10Tree、Unformat、Vsafe命令的區(qū)別與使用說(shuō)明
Tree、Unformat、Vsafe命令的區(qū)別與使用說(shuō)明...2007-03-03